Регулярное выражение для операции «И НЕ»

Я ищу общую конструкцию регулярного выражения, которая бы соответствовала всему в шаблоне 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();
}

Мне все еще интересно, есть ли собственная конструкция регулярного выражения, которая могла бы это сделать.

25
задан Joshua Honig 26 September 2011 в 00:17
поделиться

2 ответа

После ваших правок он все еще остается негативным, но с дополнительным квантификатором.

Если вы хотите убедиться, что вся строка не содержит «My», то вы можете сделать это

(?!.*My)^.*$

Смотрите здесь, в Regexr

Это будет соответствовать любой последовательности символов (с .* в конце), а (?!.*My).* в начале потерпит неудачу, когда в строке есть «My».

Если вы хотите сопоставить что-либо, что не является «Моим», тогда используйте якоря

(?!^My$).*
6
ответ дан 28 November 2019 в 21:05
поделиться

Итак, просмотрев следующие темы в RegEx: lookahead, lookbehind, вложенность, оператор AND, рекурсия, подпрограммы, условные выражения, якоря и группы, я пришел к выводу, что решения не существует это удовлетворяет тому, что вы просите.

Причина, по которой Lookahead не работает, заключается в том, что он терпит неудачу в этом относительно простом случае:

Три слова без My включены как одно.

Регулярное выражение:

^ (?!. * My. *) (\ B \ w + \ b \ s \ b \ w + \ b \ s \ b \ w + \ b)

Совпадения:

включены как одно

Первые три слова не совпадают, потому что My происходит после них. Если «Мое» находится в конце всей строки, вы никогда не найдете ничего подходящего, потому что каждое предположение потерпит неудачу, потому что они все это увидят.

Проблема, как представляется, заключается в том, что, хотя lookahead имеет неявную привязку относительно того, где он начинает свое сопоставление, нет способа завершить, где lookahead завершает свой поиск с помощью привязки, основанной на результате другой части RegEx. Это означает, что вам действительно нужно продублировать все RegEx в негативном поле зрения, чтобы вручную создать нужный якорь.

1112 Это расстраивает и причиняет боль. «Решением» является использование языка сценариев для выполнения двух регулярных выражений. Один поверх другого. Я удивлен, что такого рода функциональность лучше не встроена в движки регулярных выражений.

1
ответ дан 28 November 2019 в 21:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: