Вы можете сделать:
h.*e(?:.*l){2}.*o
Это в основном соответствует нулю или более любых символов (.*
) между желаемыми символами.
{num}
- сокращение для записи последовательныхповторяющиеся паттерны;здесь, к (?:.*l){2}
мы сопоставляем 2 последовательных паттерна .*
(помещаем в не захваченную группу (?:)
).Таким образом, вы могли бы также написать:
h.*e.*l.*l.*o
Другое дело, вы можете использовать .*?
, чтобы получить не жадное совпадение, которое сначала будет соответствовать самой короткой подстроке, а не жадно совпадать самой длинной с .*
и отслеживание назад.
h.*?e(?:.*?l){2}.*?o
Пример:
In [2112]: re.search(r'h.*e(?:.*l){2}.*o', 'kdjhslfjhshhhheeellllllooooosadsf')
Out[2112]: <re.Match object; span=(3, 28), match='hslfjhshhhheeellllllooooo'>
In [2113]: re.search(r'h.*e(?:.*l){2}.*o', 'helhcludoo')
Out[2113]: <re.Match object; span=(0, 10), match='helhcludoo'>
В своем регулярном выражении вы использовали +
, который предназначен длясоответствует одному или нескольким предыдущим токенам, например, e+
соответствует одному или нескольким e
;следовательно, ваш Regex не сможет найти нужную подстроку.