[regexp] не вхождение слова.
Самое простое, сначала найти строку a.*b, а потом проверить, что внутри нет сdefg
Допустим, мне надо сделать автозамену в более 1000 мест.
upd. А мой-то запрос не работает, придётся ещё отдельно рассматривать вхождения cb, cdb итд, что делает его ещё более громоздким
И сформулируй менее абстрактную задачу.
(ошибся, не работает)
$ perl -n -e ' /a.*b(?<!\A.*cdefg.*\G)/ and print $&, "\n"' b
Variable length lookbehind not implemented in regex m/a.*b(?<!\A.*cdefg.*\G)/ at -e line 1.
upd. А мой-то запрос не работает, придётся ещё отдельно рассматривать вхождения cb, cdb итд, что делает его ещё более громоздкимНе отловит и accdefgb.
А принципиально сделать в одно выражение? Я бы поступил как .
Можно использовать вариации, аля:
s#%#%1#g
s#cdefg#%2#g
Потом отлавливать подстроки так, например:
m#a(?:[^%]*|%1)*b#
Затем обратное преобразование:
s#%2#cdefg#g
s#%1#%#g
А конкретный запрос уже решён (преведённым способом) и не актуален. Просто казалось странным, что простого исключения там задать нельзя.
За sed спасибо, копаюсь.
но там все равно ошибка была, да и \A я не пойми зачем впихнул, черт попутал
вот, относительно правильный вариант:
(?>a?!cdefg).)*b)
правда, если у тебя "cdefg" будет перекрываться с "b" (ну, в реальных примерах может не сработать
ща еще подумаем
upd. усе работает
Это и имелось ввиду.
> А принципиально сделать в одно выражение? Я бы поступил как .
Нет, но принципиально, чтобы затраченное время не зависело от кол-ва запросов.
Возможно, то, что ты предлагаешь и не зависит, но я не помнимаю, что там написано . Это на чём вообще?
И что значит потом отлавливать подстроки? Где их отлавливать?
Я подумал, ты про такие подстроки: acb (после c должно быть что-то кроме d, а затем уже может быть b).
Я предложил такое: заменить все проценты на %1, а cdefg на %2.
Потом с полученной строкой сделать все манипуляции, а затем преобразовать %2 на cdefg, а %1 на %.
В заглядываниях запрещено использовать строки переменной длины.
не "в заглядываниях", а "в заглядываниях назад"
В заглядываниях вперед, насколько я помню, тоже.
назад и переменной длины - сложно реализовывать, большой оверхед.
но в общем случае, если b == cdefg, то не сработает.
таки фэйлит
при регексе q?!ation).)*o на слове quantization должен быть матч, а его нет
таки я не знаю как это сделать в один проход. Все равно как-то надо пометить что "дальше вот этого места - не искать".
разве что явно указать альтернативу: q(?:(?!ation).)*(?:o|atio), но это уже никак не подходит к параметризованному поиску, да
а если q?!ation).)*.{4}|.{0,4})o?
кстати с примером "a" = лол, "b" = лол, "cdefg" = ололо, и текстом "ололололо" не работает.
Лол.
a(^cfdg)*.?b$
А это не то
Хочу поискать подстроку начинающуюся с 'a', заканчивающуюся на 'b' и не содержащую 'cdefg'
попробуй это: print "$1 $2 $3 \n" if $_=~/(?<!a.*?cdefgh.*?!\b)/
написал сходу... по идее оно должно искать подстроку перед которой нет 'a' и после которой нет 'b'...
P.s. Да, а упомянутый тобою \b - это символ границы слова, а не буква b.
для множественных совпадений вот так: print "$1 $2 $3 \n" while $_=!/(?<!a.*?cdefgh.*?!\b)/gs
не проверял.. почему $1 $2 $3 - сила привычки, иногда чтото полезное видишь не там где хотелось бы.
* (?= шаблон) - после этой точки есть фрагмент текста, который соответствует указанному регулярному выражению
* (?! шаблон) - после этой точки нет текста, который бы соответствовал указанному регулярному выражению,
* (?<= шаблон) - перед этой точкой есть фрагмент текста, соответствующий указанному регулярному выражению,
* (?<! шаблон) - перед этой точкой нет фрагмента текста, соответствующего указанному регулярному выражению.
* (?#текст) - комментарий. Текст комментария игнорируется.
* (?:шаблон) или (?модификаторы:шаблон) - группирует элементы шаблона. В отличие от обычных круглых скобок, не создает нумерованной переменной. Например, модификатор i не будет делать различия между строчными и заглавными буквами, однако область действия этого модификатора будет ограничена только указанным шаблоном.
* (?=шаблон) - "заглядывание вперед". Требует, чтобы после текущей точки находился текст, соответствующий данному шаблону. Такая, конструкция обрабатывается как условие или мнимый символ, поскольку не включается В результат поиска. Например, поиск с помощью команды /w+(?=\s+)/ найдет слово, за которым следуют один или несколько "пробельных символов", однако сами они в результат не войдут.
* (?!шаблон) - случай, противоположный предыдущему. После текущей точки не должно быть текста, соотносимого с заданным шаблоном. Так, если шаблон w+(?=\s) - это слово, за которым следует "пробельный символ", то шаблон w+(?!\s) - это слово, за которым мет "пробельного символа".
* (?<=шаблон) - заглядывание назад. Требует, чтобы перед текущей точкой находился соответствующий текст. Так, шаблон (?<=\s)w+ интерпретируется как слово, перед которым имеется пробельный символ (в отличие от заглядывания вперед, заглядывание назад может работать только с фиксированным числом проверяемых символов).
* (?<!шаблон) - отрицание предыдущего условия. Перед текущей точкой не должно быть текста, соотносимого с заданным шаблоном. Соответственно, от команды /(?<!\s)w+/ требуется найти слово, перед которым нет пробельного символа.
* (?{код}) - условие (мнимый символ которое всегда выполняется. Сводится к выполнению команд perl в фигурных скобках. Вы можете использовать эту конструкцию, только если в начале сценария указана команда use re 'eval'. При последовательном соотнесении текста и шаблона, когда perl доходит до такой конструкции, выполняется указанный код. Если полного соответствия для оставшихся элементов найти не удалось, то при возврате левее данной точки шаблона вычисления, проделанные с локальными переменными, откатываются назад. (Условие является экспериментальным. В документации, прилагаемой в perl, можно найти довольно детальное рассмотрение (с примерами) работы этого условия и возможных трудностей в случае его применения.)
* (?>шаблон) - "независимый" или "автономный" шаблон. Используется для оптимизации процесса поиска, поскольку запрещает "поиск с возвратом". Такая конструкция соответствует подстроке, на которую налагается заданный шаблон, если его закрепить в текущей точке без учета последующих элементов шаблона. Например, шаблон (?>а*)аb в отличие от a*ab не может соответствовать никакой строке. Если поставить в любом месте шаблон а*, он съест все буквы а, не оставив ни одной шаблону ab. (Для шаблона а*аb "аппетит" квантификатор * будет ограничен за счет работы поиска с возвратами: после того как на первом этапе не удастся найти соответствие между шаблоном и текстом, perl сделает шаг назад и уменьшит количество букв а, захватываемых конструкцией а*.)
* (?(условие)шаблон-да|шаблон-нет) или (?(условие)шаблон-да) - условный оператор, который подставляет тот или иной шаблон в зависимости от выполнения заданного условия. Более подробно описан в документации perl.
* (?модификаторы) - задает модификаторы, которые локальным образом меняют работу процедуры поиска. В отличие от глобальных модификаторов, имеют силу только для текущего блока, то есть для ближайшей группы круглых скобок, охватывающих конструкцию, Например, шаблон ?i)text) соответcтвует слову "text" без учета регистра.
Во-первых отрицание тогда уж надо было писать как:
print "$1 $2 $3 \n" if $_!~ /(?<!a.*?cdefgh.*?!\b)/
Во-вторых, под это твоё отрицание попадёт что угодно, например:
print "Lalala\n" if "Vilfred loh" !~ /(?<!a.*?cdefgh.*?!\b)/;
Просто замечательно срабатывает, хотя искомых букв a и b там нет. Сходи регэкспы поучи лучше)
а второе яж написал сразу что не проверял регексп... копать надо в ту сторону.
Просто "этот пацак всё время говорит на языках, продолжения которых не знает". (c)
как будто ты знаешь решение. не люблю людей, которые своего ничего не предлагают, хотябы какого нибудь, а только лишь болтают с важной физиономией на лице...
Для конкретного данного случая ("a ... b" с отсутствием cdefg в промежутке) это проще всего сделать тупым проходом по строке. Иначе - проще в два регэкспа.
Оставить комментарий
danilov
Хочу поискать подстроку начинающуюся с 'a', заканчивающуюся на 'b' и не содержащую 'cdefg'.Существует ли простой способ написать такой запрос?
Я делал это запросом a([^c]|c[^d]|cd[^e]|cde[^f]|cdef[^g])*b
Это как-то громоздко при большой длине слова.
Прочтение доков не помогло.
Если такого способа нет, есть ли средства, позволяющие составлять такие запросы (желательно такие же функциональные, как regexp)?