2013-04-18 3 views
6

У меня есть строки, такие как "aaaaabbbbbbbbbbbbbbccccccccccc". Число символов может отличаться, и иногда внутри строки может быть тире, например "aaaaa-bbbbbbbbbbbbbbccccccccccc".Python split string по шаблону

Есть ли умный способ либо разделить его "aaaaa", "bbbbbbbbbbbbbb", "ccccccccccc" и получить показатели были его расколоть или просто получить индексы, без зацикливания через каждую строку? Если тире находится между шаблонами, оно может заканчиваться либо в левом, либо вправо, поскольку оно всегда обрабатывается одинаково.

Любая идея?

ответ

11

Регулярное выражение MatchObject Результаты включают индексы матча. Остается, чтобы соответствовать повторяющиеся символы:

import re 

repeat = re.compile(r'(?P<start>[a-z])(?P=start)+-?') 

соответствовали бы только, если данное письмо символ (a - z) повторяется по крайней мере один раз:

>>> for match in repeat.finditer("aaaaabbbbbbbbbbbbbbccccccccccc"): 
...  print match.group(), match.start(), match.end() 
... 
aaaaa 0 5 
bbbbbbbbbbbbbb 5 19 
ccccccccccc 19 30 

The .start() и .end() методы на результат матча дать вам точные позиции во входной строке.

Штрихов включены в матчах, но не неповторяющиеся символы:

>>> for match in repeat.finditer("a-bb-cccccccc"): 
...  print match.group(), match.start(), match.end() 
... 
bb- 2 5 
cccccccc 5 13 

Если вы хотите a- части будет матчем, просто замените + с * мультипликатором:

repeat = re.compile(r'(?P<start>[a-z])(?P=start)*-?') 
+0

Как я могу сохранить тире? Так, например, «aaaaa -», «bbbbbbbbbbbbbb», «ccccccccccccc». – Trollbrot

+0

@Fritz: Извините, я думал, что вы не хотите их. Когда я перечитываю, я вижу, что вы это делаете. Я включил их в предыдущие буквы. –

+0

Отлично! Большое спасибо. Думаю, мне следовало бы глубже заглянуть в регулярные выражения. – Trollbrot

3

Как насчет использования itertools.groupby?

>>> s = 'aaaaabbbbbbbbbbbbbbccccccccccc' 
>>> from itertools import groupby 
>>> [''.join(v) for k,v in groupby(s)] 
['aaaaa', 'bbbbbbbbbbbbbb', 'ccccccccccc'] 

Это поставит - как свои собственные подстрок, которые могут быть легко отфильтрованы.

>>> s = 'aaaaa-bbbbbbbbbbbbbb-ccccccccccc' 
>>> [''.join(v) for k,v in groupby(s) if k != '-'] 
['aaaaa', 'bbbbbbbbbbbbbb', 'ccccccccccc'] 
+0

Можете ли вы придумать хороший способ получить индексы? Лучшее, что я могу представить, это «grouped = [(k, list (g)) для k, g в группе (перечисление (s), key = lambda x: x [1])]; [(k, g [0] [0], g [-1] [0]) для k, g в группе]. В python 3, я думаю, вы могли бы использовать 'accumulate' на длинах тоже. – DSM

+0

@ DSM - Правильно. Я пропустил часть об индексах ... Не уверен, что это хороший способ получить это ... – mgilson

0
str="aaaaabbbbbbbbbbbbbbccccccccccc" 
p = [0] 
for i, c in enumerate(zip(str, str[1:])): 
    if c[0] != c[1]: 
     p.append(i + 1) 
print p 

# [0, 5, 19] 
Смежные вопросы