Регулярное выражение для остановки при первом совпадении

Мой шаблон регулярных выражений выглядит примерно так

<xxxx location="file path/level1/level2" xxxx some="xxx">

Меня интересует только часть в кавычках, привязанных к локации. Разве не должно быть так легко, как показано ниже, без жадного переключателя?

/.*location="(.*)".*/

Кажется, не работает.

6 ответов

Решение

Вы должны сделать свое регулярное выражение нежадным, потому что по умолчанию "(.*)" будет соответствовать всем "file path/level1/level2" xxx some="xxx",

Вместо этого вы можете сделать свою точку-звезду не жадной, чтобы она соответствовала как можно меньшему числу символов:

/location="(.*?)"/

Добавление ? по квантификатору (?, * или же +) делает это не жадным.

location="(.*)" будет соответствовать от "после location= до "после some="xxx если вы не сделаете это нежадным. Так что вам либо нужно .*? (т.е. сделать его не жадным) или лучше заменить .* с [^"]*,

Как насчет

.*location="([^"]*)".*

Это позволяет избежать неограниченного поиска с помощью.* И будет точно соответствовать первой цитате.

Используйте не жадное сопоставление, если ваш движок это поддерживает. Добавить? внутри захвата.

/location="(.*?)"/

Использование ленивых квантификаторов ? без глобального флага ответ.

Например,

введите описание изображения здесь

Если у вас был глобальный флаг /g тогда он соответствовал бы всем совпадениям самой низкой длины, как показано ниже. введите описание изображения здесь

В других ответах здесь не приводится полное решение для версий регулярных выражений, которые не поддерживают нежадное сопоставление. Жадные кванторы (.*?, .+? и т.д.) - это расширение Perl 5, которое не поддерживается в традиционных регулярных выражениях.

Если ваше условие остановки - это один символ, решение простое; вместо того

a(.*?)b

вы можете соответствовать

a[^ab]*b

т.е. укажите класс символов, который исключает начальный и конечный разделители.

В более общем случае вы можете кропотливо построить такое выражение, как

start(|[^e]|e(|[^n]|n(|[^d])))end

запечатлеть матч между start и первое появление end. Обратите внимание, как подвыражение с вложенными круглыми скобками объясняет ряд альтернатив, которые между ними позволяютe только если за ним не следует nd и так далее, а также позаботьтесь о том, чтобы пустая строка была одной альтернативой, которая не соответствует тому, что запрещено в этой конкретной точке.

Конечно, в большинстве случаев правильным подходом является использование подходящего парсера для формата, который вы пытаетесь проанализировать, но иногда, возможно, он недоступен, или, возможно, специализированный инструмент, который вы используете, настаивает на регулярном выражении и ничего еще.

Вот еще способ.

Вот тот, который тебе нужен. Это лениво[\s\S]*?

Первый пункт:[\s\S]*?(?:location="[^"]*")[\s\S]* Заменить: $1

Разъяснение: https://regex101.com/r/ZcqcUm/2


Для полноты картины достанется последний. Это жадный[\s\S]*

Последний пункт:[\s\S]*(?:location="([^"]*)")[\s\S]* Заменить: $1

Разъяснение: https://regex101.com/r/LXSPDp/3


Между этими двумя регулярными выражениями есть только одно различие, а именно: ?

Поскольку вы используете количественный подшаблон и как описано в Perl Doc,

По умолчанию квантифицированный подшаблон является " жадным ", то есть он будет совпадать столько раз, сколько это возможно (учитывая конкретное начальное местоположение), но при этом все остальные паттерны будут совпадать. Если вы хотите, чтобы он совпадал с минимально возможным числом раз, следуйте за квантификатором знаком "?", Обратите внимание, что значения не меняются, только "жадность":

*?        //Match 0 or more times, not greedily (minimum matches)
+?        //Match 1 or more times, not greedily

Таким образом, чтобы позволить вашему количественному шаблону сделать минимальное соответствие, следуйте за ним ?:

/location="(.*?)"/
import regex
text = 'ask her to call Mary back when she comes back'                           
p = r'(?i)(?s)call(.*?)back'
for match in regex.finditer(p, str(text)):
    print (match.group(1))

Выход: Мэри

Другие вопросы по тегам