Квантификатор регулярных выражений

#python #regex

#python #регулярное выражение

Вопрос:

У меня есть шаблон регулярного выражения следующим образом:

.*b(?P<core>[A-Z][0-9]?b.*)(?P<extra>b[0-9]  [xX][0-9] .*)?. png

Для сопоставления некоторых строк следующим образом:-

ЭКРАН ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА 5-1 F2 ОТРАЖЕНИЕ КРУГЛОЙ ВКЛАДКИ 224x18px.png

В Python я получаю следующий результат

 {u'core': u'F2 ROUND TAB REFLECTION 224x18px', u'extra': None}
  

вместо

 {u'core': u'F2 ROUND TAB REFLECTION ', u'extra': u'224x18px'}
  

Насколько я знаю, квантификатор регулярных выражений по умолчанию в python является жадным. Поэтому я думаю, что это должно сработать.

Что я делаю не так?

Комментарии:

1. Пожалуйста, в будущем правильно форматируйте код, используя ctrl k или { } кнопку над полем редактирования. Нажмите ? кнопку для получения дополнительной информации о том, как форматировать ваши сообщения.

Ответ №1:

Выражение (?P[A-Z][0-9]?b.*) , вероятно, делает не то, что вы думаете… он будет соответствовать:

  • символ
  • тогда число или нет
  • затем граница слова
  • затем абсолютно все после этого

Который поглощает все вплоть до вашего завершения .png (которое должно быть a .png )

Комментарии:

1. Я изменил файл .png на .png.

Ответ №2:

Добавьте a ? после вашего первого жадного .*

 import re
x = "UI SCREEN 5-1 F2 ROUND TAB REFLECTION 224x18px.png"
re.search(r'.*b(?P<core>[A-Z][0-9]?b.*?)(?P<extra>b[0-9] [xX][0-9] .*)?.png', x).groups()

# OUTPUT
('F2 ROUND TAB REFLECTION ', '224x18px')
  

Комментарии:

1. Это работает, большое спасибо. Но почему? ‘?’ дополнительной группы также должен быть жадным. Сначала нужно попробовать, а затем вернуться назад.

2. Насколько мне известно, первое жадное выражение будет использовать все остальное, поэтому .*? предотвратит это.

3. Насколько я понимаю, первый жадный expr потребляет как можно больше. Затем приходит 2-е жадное выражение. Он также будет потреблять как можно больше. Для достижения максимального соответствия 2-й будет выполнен обратный откат. Это правильно? или есть какой-нибудь способ добиться такого эффекта.

4. Из документации python docs.python.org/library/re.html в нем говорится, что он будет потреблять столько, сколько возможно, в жадной форме. Наличие второго жадного выражения не изменяет эту функциональность. Он ничего не говорит о попытке выражения в обратном направлении. К тому времени, когда он переходит ко второму шаблону, строка уже израсходована.

5. мы знаем.*.png соответствует любому имени файла .png. Потому что, хотя . * потребляет все, он возвращается, чтобы сопоставить .png . Здесь мой вопрос: — Из того, что вы сказали, первое жадное выражение имеет привилегии перед последним. Есть ли какой-либо способ сделать так, чтобы последнее жадное выражение имело привилегии перед первым.

Ответ №3:

Не могли бы вы написать регулярное выражение так же, как вы используете? Потому что я не вижу имени группы в вашем регулярном выражении.

 >>> re.match(r'(?P<core>[A-Z0-9- ] ) (?P<extra>[0-9] [xX][0-9] px).png', a).groups()
('UI SCREEN 5-1 F2 ROUND TAB REFLECTION', '224x18px')