не жадное регулярное выражение Python от конца строки - PullRequest
1 голос
/ 05 марта 2019

Мне нужно найти строку в Python 3, и у меня возникают проблемы с реализацией не жадной логики, начиная с конца.

Я пытаюсь объяснить на примере:

Ввод можетбыть одним из следующих

test1 = 'AB_x-y-z_XX1234567890_84481.xml' 
test2 = 'x-y-z_XX1234567890_84481.xml'
test3 = 'XX1234567890_84481.xml'

Мне нужно найти последнюю часть строки, заканчивающуюся

somestring_otherstring.xml

Во всехВ приведенных выше случаях регулярное выражение должно возвращать XX1234567890_84481.xml

Моя лучшая попытка:

result = re.search('(_.+)?\.xml$', test1, re.I).group()
print(result)

Здесь я использовал:

(_.+)?, чтобы соответствовать "_anystring" в нежадный режим

\.xml$ для совпадения с «.xml» в последней части строки

Вывод, который я получаю, неверен:

_x-y-z_XX1234567890_84481.xml

Я нашел некоторыеТАК вопросы ( ссылка ), объясняющие, что регулярное выражение начинается слева, даже с не жадным квалификатором.

Может ли кто-нибудь объяснить мне, как реализовать не жадное регулярное выражение справа?

Ответы [ 3 ]

1 голос
/ 05 марта 2019

Ваш шаблон (_.+)?\.xml$ захватывает необязательную группу с первого подчеркивания, пока он не может соответствовать .xml в конце строки, и при этом не учитывается число подчеркиваний, которое должно быть между ними.

Чтобы соответствовать только последней части, вы можете опустить группу захвата. Вы можете использовать отрицательный класс символов и использовать якорь $, чтобы утверждать конец строки, так как она является последней частью:

[^_]+_[^_]+\.xml$

Regex demo | Python demo

Это будет соответствовать

  • [^_]+ Матч 1+ раз не _
  • _ Совпадение буквально
  • [^_]+ Совпадение 1+ раз, а не _
  • \.xml$ Соответствует .xml в конце строки

Например:

import re

test1 = 'AB_x-y-z_XX1234567890_84481.xml'
result = re.search('[^_]+_[^_]+\.xml$', test1, re.I)
if result:
    print(result.group())
1 голос
/ 05 марта 2019

Не уверен, что это соответствует тому, что вы ищете концептуально как "не жадный справа" - но этот шаблон дает правильный ответ:

'[^_]+_[^_]+\.xml$'

[^_] - это класс символов, соответствующий любому символу, который не является подчеркиванием.

1 голос
/ 05 марта 2019

Вы должны использовать это регулярное выражение, чтобы захватить то, что вы хотите,

[^_]*_[^_]*\.xml

Демо

Проверьте этот код Python,

import re

arr = ['AB_x-y-z_XX1234567890_84481.xml','x-y-z_XX1234567890_84481.xml','XX1234567890_84481.xml']

for s in arr:
 m = re.search(r'[^_]*_[^_]*\.xml', s)
 if (m):
  print(m.group(0))

Отпечатки,

XX1234567890_84481.xml
XX1234567890_84481.xml
XX1234567890_84481.xml

Проблема в вашем регулярном выражении (_.+)?\.xml$ состоит в том, что (_.+)? часть начнет совпадать с первой _ и будет соответствовать чему угодно, пока не увидитлитерал .xml и все это тоже необязательно, за ним следует ?.В связи с этим в строке _x-y-z_XX1234567890_84481.xml он также будет соответствовать _x-y-z_XX1234567890_84481, что не соответствует желаемому поведению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...