Регулярное выражение Python: почему необязательное совпадение всегда возвращает ноль? - PullRequest
0 голосов
/ 30 апреля 2019

Я хотел бы поймать протокол в тексте. Если я сделаю это по:

>>> d = re.search(re.compile(r".*(?P<protocol>(http\/\d\.\d)?) (?P<statuscode>\d{3})"), 'khkhjkhkhkh HTTP/1.1 303')
>>> d.groupdict()["protocol"]

результат будет пустым, потому что для сопоставления протокола с. *, Если я уберу '?' для протокола он отлично работает в этом случае, но не работает для случаев, когда протокол отсутствует, например, 'khkhjkhkhkh 303'. Я понимаю, что регулярное выражение сбивает с толку совпадение с протоколом вместо. *, Но есть ли что-то обходное?

1 Ответ

2 голосов
/ 30 апреля 2019

Поскольку шаблон протокола является необязательным, первый .* будет максимально соответствовать (жадному) до обязательного шаблона кода состояния. Согласно комментарию, вам нужен не жадный вариант: .*?.

Вам также необходимо сопоставлять без учета регистра, так как в вашем шаблоне есть http, а в строке поиска - HTTP.

Вместе:

>>> import re
>>> regex = re.compile(r".*?(?P<protocol>(http/\d\.\d)?) (?P<statuscode>\d{3})", re.I)
>>> match = regex.search('khkhjkhkhkh HTTP/1.1 303')
>>> match.groupdict()['protocol']
'HTTP/1.1'

(Не нужно избегать косой черты.)

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