2016-04-25 4 views
3

Я думал, что хотя группа была необязательной, ?, что она все равно будет жадной и потребляющей персонажей, , если она может, прежде чем перейти к следующей части регулярного выражения.Почему моя факультативная группа не жадна? /(5)?.*/

Когда я указываю упрощенный регулярное выражение (5)?.* против (5).* (группа 1 не по желанию), я вижу другое поведение в Python 2.7.6, хотя я ожидал бы такое же поведение, используя ту же самую строку:

>>> import re 
>>> s = 'before [5.5s] after' 
>>> r = re.compile(r'(5)?.*') 
>>> print r.search(s).groups() 
(None,) 

>>> r2 = re.compile(r'(5).*') 
>>> print r2.search(s).groups() 
('5',) 

Что я не получу? Почему первое регулярное выражение, r, а не всасывание 5?

Примечание: Я нужна теория почему, так как любая попытка решения это частности регулярное выражение не поможет мне. Это номер SSCCE. У меня более сложное регулярное выражение, и я действительно хочу заполнить пробел в своих знаниях относительно , почему необязательная группа не так жадна, как я бы подумал и хотел бы.

+6

Люди никогда не перестанут задавать такие вопросы ... Поскольку '(5)?' Может соответствовать пустой строке, а так как механизм regex анализирует строку слева направо, '(5)?' Соответствует началу строка и '. *' соответствуют остальной части строки. –

+0

И все же 're.compile ('(. *) (. *)'). Search ('abc'). Groups()' yields '('abc', '')'. Ты знаешь почему? –

+0

'поиск' начинается с начала строки.Если он имеет совпадение (как в этих случаях), другие начальные индексы не учитываются. – myaut

ответ

4

Первый пример:

  • Ваше регулярное выражение сравнивается с весь строки s.
  • Таким образом, первый персонаж s, который является "b",, соответствует (5)?, что не приводит к поединку. Однако это не проблема, потому что - это часть шаблона , поэтому двигатель регулярных выражений соответствует нулю и продолжает продвигать текущее положение в шаблоне.
  • Остальная часть строки соответствует остальной части шаблона, поэтому вся строка соответствует. Однако сама группа (5) ничего не соответствовала, так что вы видите None в своем первом примере.

Второй пример:

  • 5 больше не обязательно, поэтому первый символ потенциально сопоставления строки должен быть «5». Поэтому потенциальный матч начинается с «5» после «до [».
  • Чтобы соответствовать друг другу, оставшаяся строка должна соответствовать оставшемуся рисунку .*, что и делает.

Обратите внимание, что в целом using the greedy .* is almost never what you want.

+0

Статья интересна, но название - худшее из всех времен. –

+0

@CasimiretHippolyte Прошу прощения. ;) –

+0

К сожалению, это ваше, извините. Я имею в виду, что название может привести к предположению, что нужно избегать жадных кванторов * (когда они намного быстрее, чем ленивые кванторы) *. Вы должны написать статью о способах избежать ленивых кванторов! –