Регулярное выражение соответствует четному количеству букв

Мне нужно сопоставить выражение в Python с регулярными выражениями, которое соответствует только четному числу вхождений букв. Например:

AAA        # no match
AA         # match
fsfaAAasdf # match
sAfA       # match
sdAAewAsA  # match
AeAiA      # no match

четное число As должно совпадать.

8 ответов


попробовать это регулярное выражение:

^[^A]*((AA)+[^A]*)*$

и если As не должны быть последовательными:

^[^A]*(A[^A]*A[^A]*)*$

это поиск блока с нечетным числом A. Если вы нашли один, строка плохо для вас:

(?<!A)A(AA)*(?!A)

Если я правильно понимаю, код Python должен выглядеть так:

if re.search("(?<!A)A(AA)*(?!A)", "AeAAi"):
   print "fail"

'A*' означает совпадение любого числа A. Даже 0.

вот как сопоставить строку с четным числом a, верхним или Нижним:

re.compile(r'''
    ^
    [^a]*
    (
        (
            a[^a]*
        ){2}
    # if there must be at least 2 (not just 0), change the
    # '*' on the following line to '+'
    )* 
    $
    ''',re.IGNORECASE|re.VERBOSE)

вы, вероятно, используете a в качестве примера. Если вы хотите сопоставить определенный символ, отличный от a заменить a С %s и затем вставить

[...]
$
'''%( other_char, other_char, other_char )
[...]

'*' означает 0 или более вхождений "АА"должно сработать.

вопрос в том, хотите ли вы, чтобы вещь соответствовала "AAA". В этом случае вам придется сделать что-то вроде:

r = re.compile('(^|[^A])(AA)+(?!A)',)
r.search(p)

Это будет работать для совпадения четного (и только четного) числа'.

Теперь, если вы хотите сопоставить "если есть какое-либо четное количество последующих букв", это сделает трюк:

re.compile(r'(.)')

однако это не исключает "нечетных" случаев. Но это не ясно из вашего вопроса, если вы действительно этого хотите.

обновление: Это работает для вас тестовых случаев:

re.compile('^([^A]*)AA([^A]|AA)*$')

прежде всего, обратите внимание, что /A*/ соответствует пустой строке.

во-вторых, есть некоторые вещи, которые вы просто не можете сделать с регулярными выражениями. Это будет намного проще, если вы просто пройдете через строку и подсчитаете все случаи письма, которое вы ищете.


A * означает совпадение " A " с нулем или более раз.

для четного числа " A " попробуйте: (AA)+


Это невозможно считать угодно С помощью регулярных выражений. Например, убедитесь,что у вас есть соответствующие скобки. Для подсчета вам нужна "память", которая требует чего-то по крайней мере такого же сильного, как pushdown automaton, хотя в этом случае вы можете использовать регулярное выражение, предоставленное @Gumbo.

предложение использовать finditer - лучшее решение для общего случая.


зачем так много работать, придумывая трудный для чтения шаблон? Просто найдите все вхождения шаблона и подсчитайте, сколько вы найдете.

len(re.findall("A", "AbcAbcAbcA")) % 2 == 0

Это должно быть мгновенно понятно всем опытным программистам, тогда как шаблон вроде" (?

проста лучше.