Отрицательный прогноз исключает именно указанную комбинацию

Я использую следующее регулярное выражение

@"(?![iv][iv]?[i]?)(?![.])\b[a-z]+(['-][a-z]+)*[a-z]+\b"

чтобы соответствовать слову, которое соответствует следующим критериям:

  1. Имеет 2 символа или более ([a-z]+(['-][a-z]+)*[a-z]+, материал в скобках допускает использование дефисов/апострофов)
  2. В них нет точек (?![.]) (например, кандидат наук)
  3. Не является словом, содержащим римские цифры I или V ((?![iv][iv]?[i]?)) (например, VII)

В целом это работает хорошо, но если одно из слов, скажем, Vivian, это слово будет исключено. Похоже, что Vivian исключено, потому что это слово с символами I и V. Я хочу запрограммировать отрицательный просмотр, который будет исключать только слова, состоящие ТОЛЬКО из I и/или V, например III или VII или V. Как я могу сделать отрицательный просмотр менее жадным?


person seebiscuit    schedule 27.01.2014    source источник
comment
С ?![.] вы соответствуете не ., а любому символу. . — это подстановочный знак, который соответствует чему угодно. Вам нужно использовать (?![\.])   -  person rae1    schedule 28.01.2014
comment
@ rae1 Если только механизм регулярных выражений C # не отличается от большинства основных разновидностей регулярных выражений, в квадратных скобках большинство (если не все) ключевых слов, включая ., являются буквальными.   -  person seebiscuit    schedule 28.01.2014
comment
Итак, механизм регулярных выражений C# отличается от большинство основных ароматов регулярных выражений;)   -  person rae1    schedule 28.01.2014
comment
@ rae1: У каждого варианта регулярного выражения есть свои особенности, но [.] соответствует буквальной точке в .NET, как и в любом другом известном мне варианте.   -  person Alan Moore    schedule 28.01.2014


Ответы (1)


Это ваше регулярное выражение:

(?:
   [a-zABE-HJ-KNOQ-UWYZ'-]  # Any char from the previous list is allowed except C,D,I,L,M,P,V and X
 | [CDILVX](?![IVXLCDM]+\b) # C,D,I,L,V and X allowed if not part of a roman numeral
 | M(?!r?s?\.|D\b)  # M is allowed if not part of Mr., Ms., Mrs. or roman numeral MD
 | P(?!h\.D\.)      # P is allowed if not part of Ph.D.
){2,}

Описание

Визуализация регулярных выражений

Демо

http://regex101.com/r/nP8kO2

Обсуждение

Поскольку вы используете C#, вы можете воспользоваться преимуществами вычитания класса символов, заменив в приведенное выше регулярное выражение [a-zABE-HJ-KNOQ-UWYZ'-] с [-'a-zA-Z-[CDILMPVX]]. Спасибо @Rawling.

Посмотрите его в действии на RegexHero (онлайн-тестер регулярных выражений для .СЕТЬ).

Это регулярное выражение чувствительно к своему контексту. Например, относится ли слово DIV к числу 504 римскими цифрами или к HTML-тегу div? На данный момент регулярное выражение отклонит DIV, потому что оно имеет запретную последовательность: IV.

использованная литература

person Stephan    schedule 27.01.2014
comment
Аккуратная работа! Я бы увеличил ответ еще несколько раз, если бы мог. Кстати, спасибо за ссылку на тестер регулярных выражений. Я искала такой сайт с тех пор, как избавилась от подгузников. Престижность. - person seebiscuit; 28.01.2014
comment
Мясо и картофель регулярного выражения находятся внутри незахватывающего блока. Мое ограниченное понимание блоков без захвата заключается в том, что внутри этого блока ничего не выбрано. Тем не менее... тестер регулярных выражений, кажется, соответствует логике внутри блока без захвата. Не могли бы вы объяснить, как это работает? - person seebiscuit; 28.01.2014
comment
Я снял этот вопрос, потому что слова, заканчивающиеся точкой, такие как Mr. или Ms. и т. д., не исключаются. Оставил голосование, потому что он отлично справляется со всем остальным. - person seebiscuit; 29.01.2014
comment
@Seabiscuit Я обновил свой ответ, исключив английские названия, такие как Mr. и другие. - person Stephan; 29.01.2014
comment
Может быть лучше использовать вычитание класса символов для первого большого класса символов. - person Rawling; 29.01.2014
comment
@Rawling Спасибо за вашу оптимизацию, я соответствующим образом обновил свой ответ (см. Раздел «Обсуждение»). Ваш комментарий заставил меня открыть для себя RegexHero (regexhero.net/tester) одновременно ;) - person Stephan; 29.01.2014
comment
@Alex Опять же, впечатляющие усилия. Эта версия позаботится о большинстве моих ситуаций. Однако пункт 2 в моем вопросе требует общего выражения для ЛЮБОГО слова, которое может быть аббревиатурой (например, Mrs.). Впрочем, это может быть моя вина, а не ваша. Я не упомянул, что знаю, что мне не понадобится последнее слово в предложении, поэтому ЛЮБЫЕ слова с точками для меня бесполезны. Это не связано, но будет иметь ОГРОМНОЕ значение в регулярном выражении, я использую параметр регулярного выражения IngnoreCase! - person seebiscuit; 29.01.2014