Я ищу общую конструкцию регулярного выражения, которая бы соответствовала всему в шаблоне x, ЗА ИСКЛЮЧЕНИЕМ совпадений с шаблоном y. Это трудно объяснить как полностью, так и кратко ... см. Material Nonimplication для формального определения.
Например, сопоставить любой символ слова ( \ w
), ЗА ИСКЛЮЧЕНИЕМ 'p'. Обратите внимание, что я вычитаю небольшой набор (буква «p») из большего набора (все символы слов). Я не могу просто сказать [^ p]
, потому что это не принимает во внимание больший ограничивающий набор, состоящий только из словесных символов. Конечно, для этого небольшого примера я мог бы вручную восстановить что-то вроде [a-oq-zA-OQ-Z0-9 _]
, что сложно, но выполнимо. Но я ищу более общую конструкцию, чтобы, по крайней мере, большое положительное множество могло быть более сложным выражением.Как match ((? , кроме случаев, когда оно начинается с "My" .
Править : Я понимаю, что это был плохой пример, так как исключение чего-то в начале или в конце - это ситуация, когда работают отрицательные и ретроспективные выражения. this). Итак ... как насчет исключения совпадений, содержащих "My" где-то посередине? ... Я все еще действительно ищу общую конструкцию, например, эквивалент регулярного выражения следующего псевдо-sql
select [captures] from [input]
where (
input MATCHES [pattern1]
AND NOT capture MATCHES [pattern2]
)
Если есть ответ: «его не существует, и вот почему ...» Я тоже хотел бы это знать.
Редактировать 2 : Если бы я хотел определить свою собственную функцию для этого, это было бы что-то вроде ( вот версия LINQ для C #):
public static Match[] RegexMNI(string input,
string positivePattern,
string negativePattern) {
return (from Match m in Regex.Matches(input, positivePattern)
where !Regex.IsMatch(m.Value, negativePattern)
select m).ToArray();
}
Мне все еще интересно, есть ли собственная конструкция регулярного выражения, которая могла бы это сделать.
После ваших правок он все еще остается негативным, но с дополнительным квантификатором.
Если вы хотите убедиться, что вся строка не содержит «My», то вы можете сделать это
(?!.*My)^.*$
Смотрите здесь, в Regexr
Это будет соответствовать любой последовательности символов (с .*
в конце), а (?!.*My).*
в начале потерпит неудачу, когда в строке есть «My».
Если вы хотите сопоставить что-либо, что не является «Моим», тогда используйте якоря
(?!^My$).*
Итак, просмотрев следующие темы в RegEx: lookahead, lookbehind, вложенность, оператор AND, рекурсия, подпрограммы, условные выражения, якоря и группы, я пришел к выводу, что решения не существует это удовлетворяет тому, что вы просите.
Причина, по которой Lookahead не работает, заключается в том, что он терпит неудачу в этом относительно простом случае:
Три слова без My включены как одно.
Регулярное выражение:
^ (?!. * My. *) (\ B \ w + \ b \ s \ b \ w + \ b \ s \ b \ w + \ b)
Совпадения:
включены как одно
Первые три слова не совпадают, потому что My происходит после них. Если «Мое» находится в конце всей строки, вы никогда не найдете ничего подходящего, потому что каждое предположение потерпит неудачу, потому что они все это увидят.
Проблема, как представляется, заключается в том, что, хотя lookahead имеет неявную привязку относительно того, где он начинает свое сопоставление, нет способа завершить, где lookahead завершает свой поиск с помощью привязки, основанной на результате другой части RegEx. Это означает, что вам действительно нужно продублировать все RegEx в негативном поле зрения, чтобы вручную создать нужный якорь.
1112 Это расстраивает и причиняет боль. «Решением» является использование языка сценариев для выполнения двух регулярных выражений. Один поверх другого. Я удивлен, что такого рода функциональность лучше не встроена в движки регулярных выражений.