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

Совместимость шаблонов 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 - всего лишь пример, но мне бы очень хотелось, чтобы это расширилось до большего количества букв. Меня интересуют регулярные выражения и решения без регулярных выражений.

4b9b3361

Ответ 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