Регулярное выражение соответствует четному числу букв - PullRequest
9 голосов
/ 12 января 2010

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

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

Четное число как ДОЛЖНО совпадать.

Ответы [ 8 ]

16 голосов
/ 12 января 2010

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

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

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

^[^A]*(A[^A]*A[^A]*)*$
3 голосов
/ 12 января 2010

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

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

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

if re.search("(?<!A)A(AA)*(?!A)", "AeAAi"):
   print "fail"
2 голосов
/ 12 января 2010

'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 )
[...]
1 голос
/ 12 января 2010

'*' означает 0 или более вхождений «AA» должен сделать трюк.

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

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

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

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

re.compile(r'(.)\1')

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

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

re.compile('^([^A]*)AA([^A]|AA)*$')
0 голосов
/ 12 января 2010

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

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

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

Чем проще, тем лучше.

0 голосов
/ 12 января 2010

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

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

0 голосов
/ 12 января 2010

A * означает совпадение «A» ноль или более раз.

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

0 голосов
/ 12 января 2010

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

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

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