Подтвердить что ты не робот

Что вызывает '' в ['h', 'e', ​​'l', 'l', 'o', ''], когда вы делаете re.findall('[\ w]?', 'Hello')

Что вызывает '' в ['h', 'e', 'l', 'l', 'o', ''], когда вы делаете re.findall('[\w]?', 'hello'). Я думал, что результат будет ['h', 'e', 'l', 'l', 'o'], без последней пустой строки.

4b9b3361

Ответ 1

Вопросительный знак в вашем регулярном выражении ('[\w]?') отвечает за то, что пустая строка является одним из возвращаемых результатов.

Вопросительный знак - это квантификатор, означающий "совпадение нуля или одного". Вы запрашиваете все вхождения либо нулевых символов слова. Буквы удовлетворяют совпадению символов "один или один слово". Пустая строка удовлетворяет условию соответствия "нулевые слова".

Измените регулярное выражение на '\w' (удалите вопросительный знак и лишние скобки символьного класса), и результат будет таким, как вы ожидаете.

Ответ 2

Регулярно ищет строки по одному символу за раз. Если совпадение найдено в позиции символа, регулярное выражение переходит к следующей части шаблона. Если совпадение не найдено, регулярное выражение пытается чередовать (разные варианты), если оно доступно. Если все альтернативы терпят неудачу, они возвращаются и чередуют предыдущую часть и так далее до тех пор, пока не будет найдено либо полное совпадение, либо все альтернативы не сработают. Вот почему некоторые, казалось бы, простые регулярные выражения будут быстро соответствовать строке, но не совпадают в экспоненциальном времени. В вашем примере у вас есть только одна часть вашего шаблона.

Вы ищете [\w]?. ? означает " один или ноль предыдущей части" и эквивалентен {0,1}. Каждый из 'h', 'e', 'l', 'l' и 'o' соответствует [\w]{1}, поэтому шаблон продвигается и завершается для каждой буквы, перезапуская регулярное выражение в начале, потому что вы просили все совпадения, не только первый. В конце строки регулярное выражение все еще пытается найти совпадение. [\w]{1} больше не соответствует, но альтернативный [\w]{0} делает, поэтому он соответствует ''. Современные двигатели регулярных выражений имеют правило, чтобы остановить совпадение нулевой длины от повторения в том же положении. Регулярное повторение снова пытается, но на этот раз не получается, потому что он не может найти соответствие для [\w]{1}, и он уже нашел соответствие для [\w]{0}. Он не может продвигаться по строке, потому что он в конце, поэтому он выходит. Он запустил шаблон 7 раз и нашел 6 совпадений, последний из которых был пуст.

Как указано в комментарии, если ваше регулярное выражение было \w?? (я удалил [ и ], потому что они не нужны в исходном регулярном выражении), это означает найти ноль или один (обратите внимание, что порядок изменился раньше). Он вернет '', 'h', '', 'e', '', 'l', '', 'l', '', 'o' и ''. Это связано с тем, что теперь он предпочитает находить ноль, но не может найти два совпадения нулевой длины подряд, не продвигаясь вперед.