Совместимость шаблонов Python. Match 'c [любое число последовательных a, b или c или b, cs или т.д.] T'
Извините за заголовок, я не мог придумать чистый способ задать свой вопрос.
В Python я хотел бы сопоставить выражение 'c [some stuff] t', где [some stuff] может быть любым числом последовательных a, b или c и в любом порядке.
Например, эти работы:
'ct', 'cat', 'cbbt', 'caaabbct', 'cbbccaat'
но это не так:
'cbcbbaat', 'caaccbabbt'
Изменить: a, b и c - всего лишь пример, но мне бы очень хотелось, чтобы это расширилось до большего количества букв. Меня интересуют регулярные выражения и решения без регулярных выражений.
Ответы
Ответ 1
Не уверен, как вы привязываетесь к регулярному выражению, но вот решение, использующее другой метод:
from itertools import groupby
words = ['ct', 'cat', 'cbbt', 'caaabbct', 'cbbccaat', 'cbcbbaat', 'caaccbabbt']
for w in words:
match = False
if w.startswith('c') and w.endswith('t'):
temp = w[1:-1]
s = set(temp)
match = s <= set('abc') and len(s) == len(list(groupby(temp)))
print w, "matches" if match else "doesn't match"
Строка соответствует, если набор средних символов является подмножеством set('abc')
, а число групп, возвращаемых groupby()
, совпадает с количеством элементов в наборе.
Ответ 2
Не проверено полностью, но я думаю, что это должно работать:
import re
words = ['ct', 'cat', 'cbbt', 'caaabbct', 'cbbccaat', 'cbcbbaat', 'caaccbabbt']
pat = re.compile(r'^c(?:([abc])\1*(?!.*\1))*t$')
for w in words:
print w, "matches" if pat.match(w) else "doesn't match"
#ct matches
#cat matches
#cbbt matches
#caaabbct matches
#cbbccaat matches
#cbcbbaat doesn't match
#caaccbabbt doesn't match
Это соответствует прогонам a
, b
или c
(это часть ([abc])\1*
), а отрицательный lookahead (?!.*\1)
гарантирует, что после запуска не будет присутствовать другой экземпляр этого символа.
(изменить: исправлено опечатку в объяснении)
Ответ 3
Я считаю, что вам нужно явно кодировать все возможные перестановки a
s, b
и c
s:
c(a*b*c*|b*a*c*|b*c*a*|c*b*a*|c*a*b*|a*c*b*)t
Обратите внимание, что это чрезвычайно неэффективный запрос, который может сильно отступить.
Ответ 4
Я не знаю механизм регулярных выражений Python, но похоже, что вы просто хотите напрямую записать 6 разных возможных порядков.
/c(a*b*c*|a*c*b*|b*a*c*|b*c*a*|c*a*b*|c*b*a*)t/
Ответ 5
AFAIK нет "компактного" способа сделать это...
c(a*(b*c*|c*b*)|b*(a*c*|c*a*)|c*(a*b*|b*a*))t