почему этот шаблон не может охватить все повторяющиеся символы в Python? - PullRequest
2 голосов
/ 30 апреля 2019

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

For example:

The first target of "abcabcbb" is "abca" with repeated 'a'
The first target of "abba" is "abb" with repeated 'b'
...

Я пробовал шаблоны регулярных выражений в python3.

когда я написал шаблон как:

pair = re.compile (r ". * (.). * \ 1")

получил результат как:

>>> s
['abcabcbb', '   ', 'abba', 'uqinntq']
>>> for ss in s:
...     res=pair.search(ss)
...     print(ss, res.group(), res.groups())
... 

abcabcbb abcabcbb ('b',)    ..............WRONG!
        (' ',)
abba abb ('b',)             ..............OK!
uqinntq uqinn ('n',)        ..............WRONG!

когда я изменил шаблон на:

pair = re.compile (r ". *? (.). *? \ 1")

тогда я получил:

abcabcbb abca ('a',)       ...............OK!
       (' ',)
abba abba ('a',)           ...............WRONG!
uqinntq uqinntq ('q',)     ...............WRONG!

Я понятия не имею, почему я получил эти результаты. Как я могу написать шаблон регулярного выражения в этом случае?

Ответы [ 2 ]

0 голосов
/ 30 апреля 2019

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

from collections import Counter

s = ['abcabcbb', '   ', 'abba', 'uqinntq']

for ss in s:
    #If string is non-empty
    if ss.strip():
        #This will help us calculate frequencies of all characters
        c = Counter(ss)
        print(ss)
        for key, value in c.items():
            #If characters are repeated, print them
            if value > 1:
                print('{} is repeated {} times'.format(key, value))

Вывод будет.

abcabcbb
a is repeated 2 times
b is repeated 4 times
c is repeated 2 times
abba
a is repeated 2 times
b is repeated 2 times
uqinntq
q is repeated 2 times
n is repeated 2 times
0 голосов
/ 30 апреля 2019

Вы получаете совершенно правильные результаты.

Давайте возьмем ваше первое регулярное выражение .*(.).*\1 и некоторые примеры.

Например, строка abcabcbb и здесь вы получите b.Давайте посмотрим, почему.

Ваше регулярное выражение - .*(.).*\1, которое начинается с .*, что является жадным, и это означает, что он будет потреблять как можно больше символов, обеспечивая совпадение.Так что .* захватывает abcabc, поскольку это максимально возможный захват, который может сделать .*, а (.) будет соответствовать b, а .* будет соответствовать пустой строке, и снова \1 будет соответствовать b, и этоконец матчаСледовательно, (.) захватили b, когда вы его получаете.Так что это не неправильное совпадение.

Теперь давайте возьмем пример не жадной версии регулярного выражения: .*?(.).*?\1

Пусть строка примера будет abba.Это даст вам a и давайте посмотрим, почему.

Ваше регулярное выражение .*?(.).*?\1 начинает совпадать с .*? и, следовательно, на этот раз пытается совпадать как можно меньше, следовательно, ничего не совпадает, тогда (.) соответствует aа потом .*?соответствует bb (помните, что оно должно соответствовать минимуму, но все равно генерировать совпадение) и, наконец, \1 соответствует финалу a.Вот так заканчивается матч, и вы получаете a в (.), и это правильно.

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