Вы указали следующие ограничения:
- может содержать буквы, цифры и символы подчеркивания.
- должен содержать хотя бы одну цифру
- должен содержать хотя бы одно подчеркивание
- не должен заканчиваться символом подчеркивания
- не должен начинаться с цифры
Ограничения типа «по крайней мере одно X» соответствуют состояниям в конечном автомате. Поскольку у нас есть два таких ограничения, есть 2*2=4 состояния, которые управляют тем, нужна ли нам по-прежнему цифра или символ подчеркивания. Я буду сокращать состояния:
- DU — нужна цифра, нужно подчеркивание
- Du — нужна цифра, есть подчеркивание
- dU — содержит цифру, необходимо подчеркивание
- du — есть цифра, есть подчеркивание
Теперь мы можем создать таблицу переходов состояний:
STATE TRANSITIONS
_ 0-9 a-zA-Z
----- -- --- ------
DU Du dU DU
Du Du du Du
dU du dU dU
du du du du
где DU
— начальное состояние. У вас есть дополнительные специальные требования для первого и последнего перехода состояния. Кроме того, конечное состояние может быть достигнуто только из состояния du
. На самом деле, du
само по себе могло бы быть конечным состоянием, если бы оно не было достигнуто через ввод _
. Вместе с этими другими требованиями мы получаем следующую таблицу переходов состояний. Начальное состояние — S
, а конечные состояния отмечены *
. Я исключил незаконные переходы.
STATE TRANSITIONS
_ 0-9 a-zA-Z
----- --- --- -----
S Du - DU
DU Du dU DU
Du Du du Du
dU du' dU dU
*du du' du du
du' du' du du
Состояние du'
— это состояние «мы увидели все, что нам нужно, но последним символом было подчеркивание, поэтому мы не можем здесь закончить». Эта таблица состояний не требует, чтобы после символа подчеркивания шла буква, но вы должны иметь возможность добавить это самостоятельно, используя аналогичный подход. Таблица состояний соответствует DFA, но я сомневаюсь, что вы сможете упростить ее, используя NFA.
Теперь мы можем преобразовать этот конечный автомат в регулярное выражение, но это немного утомительно, поскольку у нас есть шесть состояний (гипотеза: представленный конечный автомат уже минимален). Итеративно объединяя переходы между состояниями во фрагменты регулярных выражений и исключая состояния, мы получаем следующее регулярное выражение:
([_][_a-zA-Z]*[0-9]|[a-zA-Z][a-zA-Z]*([_][_a-zA-Z]*[0-9]|[0-9][0-9a-zA-Z]*[_]+[0-9a-zA-Z]))[0-9a-zA-Z]*([_]+[0-9a-zA-Z]+)*
Ну, если только я не ошибся. Что на данном этапе вполне вероятно.
Для такого рода проверки неудобно использовать регулярные выражения. Вместо этого используйте более простой шаблон, например [_a-zA-Z][_0-9a-zA-Z]+
, а затем проверьте, содержит ли совпавшая строка цифру и символ подчеркивания, а также соответствует ли она другим правилам, касающимся символов подчеркивания. Это хорошо работает, если идентификаторы каким-то образом разделены на языке ввода, например. пробелами или другими неидентифицирующими символами.
person
amon
schedule
01.10.2015
[AB]*A[AB]*
. И все регулярные выражения могут быть преобразованы в NFA и DFA — здесь вы не используете какие-либо функции регулярных выражений, которые сделали бы ваш язык нерегулярным. - person Kilian Foth   schedule 01.10.2015XX*
можно сократить доX+
(этот шаблон можно найти дважды в вашем регулярном выражении). - person sp00m   schedule 01.10.2015_
в комментариях. Всегда используйте обратные кавычки, чтобы цитировать их, в противном случае они используются как курсив. Так что ваш предыдущий комментарий не читается. Но если вы говорите, чтоp__k
правильно, то вам нужно быть более точным, потому что за первым_
не следует буква. - person rici   schedule 01.10.2015p_
следует буква p - person   schedule 01.10.2015p_
за буквой следует символ подчеркивания, а не наоборот. Вp_9
за буквой p также следует символ подчеркивания, а в_uy_
последнее подчеркивание также стоит рядом с буквойy
. Точность важна. - person rici   schedule 01.10.2015p_9
,t_5
и_uy_
? Во всех этих случаях подчеркивание имеет букву либо слева, либо справа. - person rici   schedule 06.10.2015_uy9
,p_9
,p_p9
неправильно_uy_
,p__9
,y_9u
,y_y
,7_y
,__
- person   schedule 07.10.2015y_9u
?y_y
?7_y
? Во всех трех подчеркивание находится рядом сy
. - person rici   schedule 08.10.2015y_9u
верно, ноy_y
не содержит цифры,7_y
содержит цифру, но первый символ не может быть цифрой - person   schedule 13.10.2015