Как "обратное совпадение" с регулярным выражением?
Я использую RegexBuddy, но у меня все равно проблемы с этим:\
Я обрабатываю построчно файл. Я построил "линейную модель", чтобы соответствовать тому, что я хочу.
Теперь я хотел бы сделать обратное сопоставление... т.е. я хочу сопоставить строки, где есть строка из 6 букв, но только если эти шесть букв не являютсяАндреа, как мне это сделать?
РЕДАКТИРОВАТЬ: Я напишу программу, которая использует это регулярное выражение, я еще не знаю, если в Python или PHP, я делаю эту вещь сначала, чтобы выучить некоторое регулярное выражение:) Есть разные типы строк, я хотел бы использовать регулярное выражение чтобы выбрать интересующий меня тип. Как только я получу эти строки, я должен применить другой фильтр, просто чтобы не соответствовать известному значению, мне нужны все остальные, а не это. (?! Не хотел) работает довольно хорошо, спасибо.:-)
Я надеюсь, что это проясняет вопрос:)
10 ответов
(?!Andrea).{6}
Предполагая, что ваш движок регулярных выражений поддерживает негативные взгляды..
Редактировать: .. или, возможно, вы бы предпочли использовать [A-Za-z]{6}
на месте .{6}
Edit (снова): обратите внимание, что lookaheads и lookbehinds, как правило, не являются правильным способом "инвертировать" совпадение регулярного выражения. Регулярные выражения на самом деле не настроены для выполнения отрицательного соответствия, они оставляют это на любом языке, с которым вы их используете.
Для Python / Java,
^(.(?!(some text)))*$
http://www.lisnichenko.com/articles/javapython-inverse-regex.html
Обновлено с обратной связью от Alan Moore
В PCRE и аналогичных вариантах вы можете создать регулярное выражение, соответствующее любой строке, не содержащей значения:
^(?:(?!Andrea).)*$
Это называется закаленным жадным жетоном. Недостатком является то, что он не работает хорошо.
Какой язык вы используете? Для этого важны возможности и синтаксис реализации регулярных выражений.
Вы могли бы использовать прогнозирование. Используя Python в качестве примера
import re
not_andrea = re.compile('(?!Andrea)\w{6}', re.IGNORECASE)
Чтобы сломать это:
(?! Андреа) означает "совпадать, если следующие 6 символов не являются" Андреа ""; если так то
\w означает "символ слова" - буквенно-цифровые символы. Это эквивалентно классу [a-zA-Z0-9_]
\w {6} означает ровно 6 символов слова.
re.IGNORECASE означает, что вы исключите "Андреа", "Андреа", "Андреа"...
Другой способ - использовать логику вашей программы - использовать все строки, не соответствующие Андреа, и ввести их через второе регулярное выражение, чтобы проверить наличие 6 символов. Или сначала проверьте по крайней мере 6 символов слова, а затем убедитесь, что он не соответствует Андреа.
Отрицательное прогнозное утверждение
(?!Andrea)
Это не совсем перевернутое совпадение, но это лучшее, что вы можете напрямую сделать с помощью регулярных выражений. Не все платформы поддерживают их все же.
Если вы хотите сделать это в RegexBuddy, есть два способа получить список всех строк, не соответствующих регулярному выражению.
На панели инструментов на панели "Тест" установите область тестирования "Строка за строкой". Когда вы это сделаете, элемент "Список всех строк без соответствий" появится под кнопкой "Список всех строк" на той же панели инструментов. (Если вы не видите кнопку "Список всех", нажмите кнопку "Совпадение" на главной панели инструментов.)
На панели GREP можно включить флажки "на основе строк" и "инвертировать результаты", чтобы получить список несоответствующих строк в файлах, через которые вы просматриваете.
Я только что придумал этот метод, который может быть аппаратно интенсивным, но он работает:
Вы можете заменить все символы, которые соответствуют регулярному выражению, пустой строкой.
Это oneliner:
notMatched = re.sub(regex, "", string)
Я использовал это, потому что я был вынужден использовать очень сложное регулярное выражение и не мог понять, как инвертировать каждую его часть.
Это вернет вам только строковый результат, а не объекты соответствия!
(?!
полезно на практике. Хотя, строго говоря, взгляд в будущее не является регулярным выражением, как определено математически.
Вы можете написать обратное регулярное выражение вручную.
Вот программа для автоматического расчета результата. Его результат генерируется машиной, что обычно намного сложнее, чем ручная запись. Но результат работает.
Если у вас есть возможность сделать два совпадения регулярных выражений для обратного и соединить их вместе, вы можете использовать две группы захвата, чтобы сначала захватить все, прежде чем ваше регулярное выражение
^((?!yourRegex).)*
а затем зафиксируйте все, что находится за вашим регулярным выражением
(?<=yourRegex).*
Это работает для большинства регулярных выражений. Одна проблема, которую я обнаружил, заключалась в том, что в конце у меня был квантификатор вроде {2,4}. Тогда вам нужно проявить творческий подход.
В Perl вы можете сделать
process($line) if ($line =~!/Andrea/);