[regexp] не вхождение слова.
Самое простое, сначала найти строку a.*b, а потом проверить, что внутри нет сdefg
А как можно тем же запросом проверить?
Допустим, мне надо сделать автозамену в более 1000 мест.
upd. А мой-то запрос не работает, придётся ещё отдельно рассматривать вхождения cb, cdb итд, что делает его ещё более громоздким
Допустим, мне надо сделать автозамену в более 1000 мест.
upd. А мой-то запрос не работает, придётся ещё отдельно рассматривать вхождения cb, cdb итд, что делает его ещё более громоздким
Написать программу на sed или perl
И сформулируй менее абстрактную задачу.
И сформулируй менее абстрактную задачу.
(ошибся, не работает)
Я не знаю какие ты читаешь доки, но
$ 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
Менее абстрактная задача не решит проблему, так как именно хотелось узнать, умеет ли такое regexp, и если нет, то чем его можно заменить.
А конкретный запрос уже решён (преведённым способом) и не актуален. Просто казалось странным, что простого исключения там задать нельзя.
За sed спасибо, копаюсь.
А конкретный запрос уже решён (преведённым способом) и не актуален. Просто казалось странным, что простого исключения там задать нельзя.
За sed спасибо, копаюсь.
т.к. я сижу под виндой, пользую софт от JGSoft, собственно, и доки их.
но там все равно ошибка была, да и \A я не пойми зачем впихнул, черт попутал
вот, относительно правильный вариант:
(?>a?!cdefg).)*b)
правда, если у тебя "cdefg" будет перекрываться с "b" (ну, в реальных примерах может не сработать
ща еще подумаем
upd. усе работает
но там все равно ошибка была, да и \A я не пойми зачем впихнул, черт попутал
вот, относительно правильный вариант:
(?>a?!cdefg).)*b)
правда, если у тебя "cdefg" будет перекрываться с "b" (ну, в реальных примерах может не сработать
ща еще подумаем
upd. усе работает
> Не отловит и accdefgb
Это и имелось ввиду.
> А принципиально сделать в одно выражение? Я бы поступил как .
Нет, но принципиально, чтобы затраченное время не зависело от кол-ва запросов.
Возможно, то, что ты предлагаешь и не зависит, но я не помнимаю, что там написано . Это на чём вообще?
И что значит потом отлавливать подстроки? Где их отлавливать?
Это и имелось ввиду.
> А принципиально сделать в одно выражение? Я бы поступил как .
Нет, но принципиально, чтобы затраченное время не зависело от кол-ва запросов.
Возможно, то, что ты предлагаешь и не зависит, но я не помнимаю, что там написано . Это на чём вообще?
И что значит потом отлавливать подстроки? Где их отлавливать?
> Это и имелось ввиду.
Я подумал, ты про такие подстроки: acb (после c должно быть что-то кроме d, а затем уже может быть b).
Я предложил такое: заменить все проценты на %1, а cdefg на %2.
Потом с полученной строкой сделать все манипуляции, а затем преобразовать %2 на cdefg, а %1 на %.
Я подумал, ты про такие подстроки: acb (после c должно быть что-то кроме d, а затем уже может быть b).
Я предложил такое: заменить все проценты на %1, а cdefg на %2.
Потом с полученной строкой сделать все манипуляции, а затем преобразовать %2 на cdefg, а %1 на %.
В заглядываниях запрещено использовать строки переменной длины.
как, ты тоже читать умеешь?
не "в заглядываниях", а "в заглядываниях назад"
не "в заглядываниях", а "в заглядываниях назад"

Прикинь, да?
В заглядываниях вперед, насколько я помню, тоже.
В заглядываниях вперед, насколько я помню, тоже.
в этом не прав. вперёд - всё можно.
назад и переменной длины - сложно реализовывать, большой оверхед.
назад и переменной длины - сложно реализовывать, большой оверхед.
Нда, так можно...
но в общем случае, если b == cdefg, то не сработает.
но в общем случае, если b == cdefg, то не сработает.
майндфак
таки фэйлит
при регексе q?!ation).)*o на слове quantization должен быть матч, а его нет
таки я не знаю как это сделать в один проход. Все равно как-то надо пометить что "дальше вот этого места - не искать".
разве что явно указать альтернативу: q(?:(?!ation).)*(?:o|atio), но это уже никак не подходит к параметризованному поиску, да
таки фэйлит
при регексе q?!ation).)*o на слове quantization должен быть матч, а его нет
таки я не знаю как это сделать в один проход. Все равно как-то надо пометить что "дальше вот этого места - не искать".
разве что явно указать альтернативу: q(?:(?!ation).)*(?:o|atio), но это уже никак не подходит к параметризованному поиску, да
а если q?!ation).)*.{4}|.{0,4})o?
кстати с примером "a" = лол, "b" = лол, "cdefg" = ололо, и текстом "ололололо" не работает.
Лол.
a(^cfdg)*.?b$
Это, вроде как, a, затем несколько раз (или 0) (символ, не совпадающей с c)fdg, а затем ещё что-то не пустое, затем b
А это не то
А это не то
Хочу поискать подстроку начинающуюся с 'a', заканчивающуюся на 'b' и не содержащую 'cdefg'
попробуй это: print "$1 $2 $3 \n" if $_=~/(?<!a.*?cdefgh.*?!\b)/
написал сходу... по идее оно должно искать подстроку перед которой нет 'a' и после которой нет 'b'...
Во-первых, что ты подразумеваешь под $1 и $3? У тебя здесь будет захватываться только одна подстрока. А во-вторых, ты пытаешься решить ровно противоположную задачу.
P.s. Да, а упомянутый тобою \b - это символ границы слова, а не буква b.
P.s. Да, а упомянутый тобою \b - это символ границы слова, а не буква b.
для инвертирования так: print "$1 $2 $3 \n" if $_=!/(?<!a.*?cdefgh.*?!\b)/
для множественных совпадений вот так: print "$1 $2 $3 \n" while $_=!/(?<!a.*?cdefgh.*?!\b)/gs
не проверял.. почему $1 $2 $3 - сила привычки, иногда чтото полезное видишь не там где хотелось бы.
для множественных совпадений вот так: 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" без учета регистра.
Замечательная шпаргалка, если бы ты ей еще пользовался. Твой регэксп опять - унылая хуйня.
Во-первых отрицание тогда уж надо было писать как:
Во-вторых, под это твоё отрицание попадёт что угодно, например:
Просто замечательно срабатывает, хотя искомых букв a и b там нет. Сходи регэкспы поучи лучше)
Во-первых отрицание тогда уж надо было писать как:
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)?