почему в регулярном выражении python не могут (h)* и (h) выдавать одинаковый результат?

#python #regex #python-3.x

#python #регулярное выражение #python-3.x

Вопрос:

Я изучаю re модуль на python. Я нашел кое-что, что не имеет смысла (для меня), и я не знаю почему. Вот небольшой пример,

 x=re.compile(r'(ha)*')
c=x.search('the man know how to hahahaha')
print(c.group())#output will be nothing,no error.But i expect "hahahaha"
  

то же самое происходит, если я использую re.compile(r'(ha)?') ,

 x=re.compile(r'(ha)?')
c=x.search('the man know how to hahahaha')
print(c.group())#output will be nothing,no error.But i expect "ha". 
  

Но если я использую re.compile(r'(ha) ') ,

 x=re.compile(r'(ha) ')
c=x.search('the man know how to hahahaha')
print(c.group())#output will be `hahahaha`,just as expected.
  

Почему это, не re.compile(r'(ha)*') и re.compile(r'(ha) ') одно и то же в данном случае?

Ответ №1:

Шаблон r'h ' и r'h*' не идентичны, вот почему они не выдают одинаковый результат. подразумевает 1 или более совпадений вашего шаблона, * ноль или более:

re.search возвращает «ничего», потому что просматривается только первое совпадение. Первое совпадение для * — это нулевое совпадение вашего '(ha)' шаблона с первой буквой вашей строки:

 import re
x=re.compile(r'(ha)*')
c=x.findall('the man know how to hahahaha')   # get _all_ matches
print(c) 
  

Вывод:

 ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'ha', '']

# t   h  e        m   a   n       k   n   o   w      h    o   w       t   o      hahahaha 
  

* и ? квантификатор допускают 0 совпадений

Doku:

Pattern.search(строка[, pos[, endpos]])
Просматривайте строку в поисках первого местоположения, где это регулярное выражение выдает совпадение, …
(источник: https://docs.python.org/3/library/re.html#re.Pattern.search )

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

1. Спасибо за ответ, но если в последнем три «ha», почему оно выдает только одно «ha»?

2. @Tom (ha)* сопоставляет значения от 0 до n ha — таким образом, полное совпадение hahahaha , но вы фиксируете только одно из них внутри вашей группировки-скобки: ваша группировка содержит только одно '(ha)' . — измените шаблон на, r'((?:ha)*)' если вы хотите, чтобы все ha совпадали. Когда вы новичок в regex- используйте regex101.com и установите режим на python для эксперимента. Это даже объяснит вам ваши шаблоны.