Регулярное выражение с использованием отрицательного lookbehind не работает в Notepad++
у меня есть исходный файл с буквально сотнями вхождений строки flecha.jpg
и flecha1.jpg
, но мне нужно найти вхождения любой другой .jpg
изображение (т. е. casa.jpg
, moto.jpg
и т. д.)
Я попытался использовать регулярное выражение с отрицательным lookbehind, например:
(?<!flecha|flecha1).jpg
но это не работает! Notepad++ просто говорит, что это недопустимое регулярное выражение.
Я пробовал регулярное выражение в другом месте, и оно работает, здесь пример поэтому я думаю, что это проблема с обработкой регулярных выражений NPP или с синтаксисом lookbehinds/lookaheads.
так как смог я достигнуть такого же результата regex в NPP?
если это полезно, я использую Notepad++ версии 6.3 Unicode
в качестве дополнительного, если вы так добры, каким будет синтаксис для достижения того же самого, но с необязательными номерами (в данном случае только '1') в качестве суффикса моей строки? (даже если он не работает в НПП, как раз к знать.)..
пробовал (?<!flecha[1]?).jpg
но это не работает. Он должен работать так же, как и другое регулярное выражение, см. здесь (RegExr)
3 ответов
Notepad++ кажется не реализовали переменную длину look-behinds (это случается с некоторыми инструментами). Обходной путь-использовать более одного взгляда с фиксированной длиной:
(?<!flecha)(?<!flecha1)\.jpg
как вы можете увидеть, совпадения те же. Но это работает с АЭС.
обратите внимание, что я избежал .
, так как вы пытаетесь сопоставить расширения, то, что вы хотите, это литерал .
. То, что у тебя было, было подстановочным знаком - могло быть любым. характер.
о дополнительном вопросе, к сожалению, поскольку мы не можем иметь переменные длины look-behinds, невозможно иметь дополнительные суффиксы (числа) без наличия нескольких look-behinds.
решение проблемы ограничения переменной длины-отрицательного-lookbehind в Notepad++
Ниже приведены несколько стратегий для работы вокруг этого ограничения в Notepad++ (или любой движок регулярных выражений с тем же ограничением)
постановка проблемы
Notepad++ не поддерживает использование отрицательных утверждений lookbehind переменной длины, и было бы неплохо иметь некоторые обходные пути. Давайте рассмотрим пример в исходном вопросе, но предположим, мы хотим избежать появления файлов с именем flecha
с любой количество знаков после flecha
, и с любыми символами перед flecha
. В этом случае регулярное выражение, использующее отрицательный lookbehind переменной длины, будет выглядеть как (?<!flecha[0-9]*)\.jpg
.
строки не хочу в этом матче пример
flecha.jpg
flecha1.jpg
flecha00501275696.jpg
aflecha.jpg
img_flecha9.jpg
abcflecha556677.jpg
Стратегии
-
Вставка Временных Маркеров
начните с выполнения поиска и замены на экземплярах, с которыми вы хотите избежать работы - в нашем случае, экземпляры
flecha[0-9]*\.jpg
. Вставить специальный маркер в форме, больше нигде не появляется. Для этого примера мы вставим extra.
до.jpg
, предполагая, что..jpg
не появляется в другом месте. Так мы и делаем:найти:
(flecha[0-9]*)(\.jpg)
заменить на:
.
теперь вы можете искать свой документ для всех других
.jpg
имена файлов с простым регулярным выражением типа\w+\.jpg
или(?<!\.)\.jpg
и делайте с ними, что хотите. Когда вы закончите, выполните заключительную операцию поиска и замены, где вы замените все экземпляры..jpg
С.jpg
, чтобы удалить временную метку. -
использование отрицательного утверждения lookahead
отрицательное утверждение lookahead можно использовать, чтобы убедиться, что вы не соответствуете нежелательным именам файлов:
(?<!\S)(?!\S*flecha\d*\.jpg)\S+\.jpg
ломая его:
-
(?<!\S)
гарантирует, что ваш матч начинается в начале имени файла, а не в середине, утверждая, что ваш матч не предшествует символ без пробелов. -
(?!\S*flecha\d*\.jpg)
гарантирует, что все, что соответствует не содержит шаблон, который мы хотим избежать -
\S+\.jpg
это то, что на самом деле сопоставляется-строка символов без пробелов, за которыми следует.jpg
.
-
-
использование нескольких отрицательных lookbehinds фиксированной длины
это быстрое (но не очень элегантное) решение для ситуаций, когда шаблон, который вы не хотите сопоставлять, имеет небольшой количество возможных длин.
например, если мы знаем, что
flecha
следует только до трех цифр, наше регулярное выражение может быть:(?<!flecha)(?<!flecha[0-9])(?<!flecha[0-9][0-9])(?<!flecha[0-9][0-9][0-9])\.jpg
вы знаете, что вы только соответствуете (в смысле потребления) расширение (.jpg
)? Я бы подумал, что вы хотите сопоставить все имя файла, нет? И это гораздо проще сделать с lookahead:
\b(?!flecha1?\b)\w+\.jpg
первый \b
анкеры матч в начале имени (если это действительно именем мы ищем). Тогда (?!flecha1?\b)
утверждает, что имя не flecha
или flecha1
. Как только это будет сделано,\w+
идет вперед и потребляет имя. Тогда \.jpg
захватывает расширение, чтобы закончить матч.