Нахождение последовательности символов в строке - PullRequest
0 голосов
/ 19 февраля 2019

Используя python, я пытаюсь найти любую последовательность символов в строке, указав длину этой цепочки символов.

Например, если у нас есть следующая переменная, я хочу извлечь любую идентичную последовательность символов длиной 5:

x = "jhg**11111**jjhgj**11111**klhhkjh111ljhjkh1111"

результат должен быть:

11111
11111

как я могу это сделать?

Ответы [ 6 ]

0 голосов
/ 19 февраля 2019

Давайте немного изменим исходную строку:

x = "jhg**11111**jjhgj**22222**klhhkjh33333jhjkh44444"

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

pat = r'(.)\1{4}'

Здесь у вас есть группа захвата (один символ) и обратная ссылка на нее(4 раза), поэтому один и тот же символ должен встречаться 5 раз.

Один из вариантов печати результата, хотя и менее интуитивно понятный:

res = re.findall(pat, x)
print(res)

Но приведенный выше код печатает:

['1', '2', '3', '4']

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

Поэтому я предлагаю также второй вариант, с finditer и печатью как начальной позиции, так и целого соответствия:

for match in re.finditer(pat, x):
    print('{:2d}: {}'.format(match.start(), match.group()))

Для приведенных выше данных результат будет:

 5: 11111
19: 22222
33: 33333
43: 44444
0 голосов
/ 19 февраля 2019

Очень некрасивое решение: -)

x = "jhg**11111**jjhgj**11111**klhhkjh22222jhjkh1111"
for c, i in enumerate(x):
    if i == x[c+1:c+2] and i == x[c+2:c+3] and i == x[c+3:c+4] and i == x[c+4:c+5]:
        print(x[c:c+5])
0 голосов
/ 19 февраля 2019

Или, если вы в порядке с использованием регулярных выражений, делает ваш код намного чище:

[row[0] for row in re.findall(r'((.)\2{4,})', s)]

regex101 - пример

0 голосов
/ 19 февраля 2019

попробуйте это:

x = "jhg**11111**jjhgj**11111**klhhkjh111ljhjkh1111"

seq_length = 5

for item in set(x):
    if seq_length*item in x:
        for i in range(x.count(seq_length*item)):
            print(seq_length*item)

это работает, используя set(), чтобы легко построить последовательность, которую вы ищете, а затем ищет ее в тексте

выводит желаемый результат:

11111
11111
0 голосов
/ 19 февраля 2019

Оригинальный ответ (ниже) предназначен для другой проблемы (определение повторяющихся шаблонов n символов в строке).Вот один из возможных способов решения проблемы:

x = "jhg**11111**jjhgj**11111**klhhkjh111ljhjkh1111"
n = 5
res = [x[i:i + n] for i, c in enumerate(x) if x[i:i + n] == c * n]
print(res)
# ['11111', '11111']

Оригинальный (неправильный) ответ

Использование Counter:

from collections import Counter

x = "jhg**11111**jjhgj**11111**klhhkjh111ljhjkh1111"
n = 5
c = Counter(x[i:i + n] for i in range(len(x) - n + 1))
for k, v in c.items():
    if v > 1:
        print(*([k] * v), sep='\n')

Вывод:

**111
**111
*1111
*1111
11111
11111
1111*
1111*
111**
111**
0 голосов
/ 19 февраля 2019

itertools на помощь:)

>>> import itertools
>>> val = 5
>>> x
'jhg**11111**jjhgj**11111**klhhkjh111ljhjkh1111'
>>> [y[0]*val for y in itertools.groupby(x) if len(list(y[1])) == val]
['11111', '11111']

Редактировать: хорошо называть

>>> [char*val for char,grouper in itertools.groupby(x) if len(list(grouper)) == val]
['11111', '11111']

Или более эффективный по памяти oneliner, предложенный @Chris_Rands

>>> [k*val for k, g in itertools.groupby(x) if sum(1 for _ in g) == val]
...