#python #регулярные_выражения
Не могу понять, когда используются сверхжадные квантификаторы. Не пойму как они работают и зачем нужны. Поясните пожалуйста на примере, как работают квантификаторы этого типа и чем отличается их принцип работы от ленивых и жадных. Хотел найти пример, где поиск по одной строке с использованием разных типов квантификаторов давал бы разные результаты. Помогите разобраться.
Ответы
Ответ 1
"\"'\' Регулярки / "(\\"|[^"])*?' / // ленивый найдет "\"' / "(\\"|[^"])*' / // жадный найдет "\"'\' // потому-что хоть он и жадный, но он "позаботится, чтобы одинарная кавычка досталась тому, кто её ищет" / "(\\"|[^"])*+' / // "сверхжадный" не будет совпадения // потому-что ([^"]|\\")*+ найдет последнюю одинарную кавычку (которая не двойная [^"]) и "съест её и ему плевать, что кто-то её ищет" Ленивый квантификатор после каждого (\\"|[^"])*? ищет ' - когда нашел останавливается. Жадный квантификатор после каждого (\\"|[^"])* ищет ' - когда нашел запоминает и ищет дальше, если потом проигнорировав ' он находит новую "правильную" последовательность, (\\"|[^"])* которая завершается на ', то запоминает её. В конце выдает самую большую последовательность. "Сверхжадный" квантификатор после каждого (\\"|[^"])*+ ищет (\\"|[^"])*+ пока не найдет, все, что ему подходит. И только потом ищет '. (Регулярка / "(\\"|[^"])*' / никогда ничего не найдет). Дальше лирика. Этот пример - небольшое видоизменение того, что я нашел на Хабре (изменение для того - чтобы в сравнении ленивый квантификатор давал свое уникальное значение). А на хабре автор описывал такую историю. Кто-то хотел сделать регулярку для поиска текста в кавычках one two "foo:=\"quux\"; print" three "four" //чтобы получить "foo:=\"quux\"; print" Предложили регулярку / " ( \\" | [^"] )* " / 1 " ищем кавычку, 2 и 3 ( \\" | [^"] )* 2 \\" ищем слеш с кавычкой, 3 [^"] если не видим слеш - проверяем что символ не кавычка, 4 " если за всем найденным добром есть кавычка, то регулярка нашлась (но жадный квантификатор поищет можно ли съесть побольше текста, "сверхжадный" квантификатор сюда не пропустит пока не найдет ВСЕ, что ему подходить) ВОТ самое неинтересное! / " ( \\" | [^"] )* " / находит "\" (хотя "\" - это открытая кавычка + экранированная кавычка, а закрывающей то нет) а, / " ( \\" | [^"] )*+ " / НЕ находит "\" но находит "\"" ( "\"" - это открытая кавычка + экранированная кавычка + закрывающая кавычка) Потому-что жадный квантификатор * все равно "позаботится" о том, чтобы последняя кавычка была найдена. А "сверхжадный" квантификатор "наплюет", что кто-то там что-то ищет ему и самому нужно \" найти. P.s.: Вообще я не знал тему "сверхжадные квантификаторы". Теперь знаю. :) P.s.2:А "когда используются" и "зачем нужны" тогда, когда наша задача соответствует их логике. Как писал автор на хабре Оказывается, они очень полезны тогда, когда «откат» движка регексов назад для нас нежелателен. А как показывает практика, откат не всегда желателен… если, конечно, речь не идёт о растрате казенных денег ;-) ... На самом деле, для столь простой задачи как поиск «закавыченного» текста никакие продвинутые возможности вроде possessive quantifiers не нужны. Следующий регекс замечательно справится с этой задачей:/" ( \\. | [^"\\] )* "/x От себя добавлю что "новомодный" /"(\\"|[^"])*+"/ не найдет "\\" (хотя это кавычка + экранированный слеш + кавычка). А "старенький" /"(\\.|[^"\\])*"/- найдет "\\". Мне не встречались задачи, которые невозможно решить без "сверхжадного" квантификатора. Гонятся за ним ради прироста производительности - нелепо. Прирост не будет серьезным (если будет), а логика поиска меняется.
Комментариев нет:
Отправить комментарий