Соответствие регулярных выражений .NET - PullRequest
5 голосов
/ 09 апреля 2011

В общих чертах: как сопоставить слово с правилами регулярных выражений для а) начала, б) всего слова и в) конца?

Более конкретно: как сопоставить выражение длины>= 1, который имеет следующие правила:

  1. Не может иметь ни одного из:!@ #
  2. Не может начинаться с пробела или =
  3. Не может заканчиваться пробелом

Я пытался:

^[^\s=][^!@#]*[^\s]$

Но^[^\s=] совпадение перемещается после первого символа в слове.Следовательно, это также соответствует словам, которые начинаются с '!'или «@» или «#» (например, «#ab» или «@aa»).Это также заставляет слово иметь по крайней мере 2 символа (один начальный символ, который не является пробелом или = - и один непробельный символ в конце).

Я получил:

^[^\s=(!@#)]\1*$

для регулярного выражения, соответствующего первым двум правилам.Но как мне сопоставить отсутствие пробелов в слове с разрешением слова длиной 1?

Ответы [ 2 ]

4 голосов
/ 09 апреля 2011

Решение Cameron является одновременно точным и эффективным (и должно использоваться для любого производственного кода, где скорость должна быть оптимизирована).Ответ, представленный здесь, менее эффективен, но демонстрирует общий подход к применению логики с использованием регулярных выражений.

Вы можете использовать несколько положительных и отрицательных утверждений регулярного выражения (все применяются в одном месте в целевой строке - обычно это начало), чтобы применить несколько логических ограничений для соответствия.Приведенное ниже регулярное выражение демонстрирует, как легко это сделать для данного примера.Вам нужно понять, как движок регулярных выражений в действительности соответствует (и не совпадает), чтобы найти правильные выражения, но это не сложно, как только вы освоите его.

foundMatch = Regex.IsMatch(subjectString, @"
    # Match 'word' meeting multiple logical constraints.
    ^             # Anchor to start of string.
    (?=[^!@#]*$)  # It cannot have any of: ! @ #,      AND
    (?![ =])      # It cannot begin with a space or =, AND
    (?!.*\S$)     # It cannot end with a space,        AND
    .{1,}         # length >= 1 (ok to match special 'word')
    \z            # Anchor to end of string.
    ", 
    RegexOptions.IgnorePatternWhitespace);

Это приложение«regex-logic» часто используется для комплексной проверки пароля.

3 голосов
/ 09 апреля 2011

Ваша первая попытка была очень близка. Вам нужно только исключить больше символов для первой и последней частей и сделать необязательными две последние части:

^[^\s=!@#](?:[^!@#]*[^\s!@#])?$

Это гарантирует, что все три раздела не будут содержать ни одного из !@#. Затем, , если слово имеет длину более одного символа, оно должно заканчиваться не пробелом, а только выбранные символы заполняют пробел между ними. Это все выполняется правильно из-за якорей ^ и $.

Я не совсем уверен, что соответствует вашему второму примеру, поскольку () следует воспринимать как литеральные символы при внедрении в класс символов, а не как группу захвата.

...