2013-04-18 22 views
6

"aaaaabbbbbbbbbbbbbbccccccccccc"のような文字列があります。 文字の数が異なる場合があり、"aaaaa-bbbbbbbbbbbbbbccccccccccc"のように文字列内にダッシュがあることがあります。パターン別のPython分割文字列

のいずれか、それを分割する任意のスマートな方法があります"aaaaa""bbbbbbbbbbbbbb""ccccccccccc"、それはすべての文字列をループせずに、分割または単にインデックスを取得されたのインデックスを取得しますか?ダッシュがパターンの間にある場合、常に同じように処理される限り、左または右のいずれかに終わる可能性があります。

答えて

11

正規表現MatchObjectの結果には、一致するインデックスが含まれています。少なくとも一度繰り返される - 指定した文字の文字(za)があれば

import re 

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

のみ一致します:試合結果に

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

.start().end()方法をどのような残っているのは、繰り返し文字を一致させることです入力文字列の正確な位置を指定します。

ダッシュは試合には含まれませんが、非反復文字:あなたはa-一部が試合にしたい場合は

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

は、単に*乗数で+を置き換える:

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

どのように私はダッシュを維持することができますか? たとえば "aaaaa - "、 "bbbbbbbbbbbbbbb"、 "ccccccccccc"です。 – 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

インデックスを取得するいい方法があると思いますか?私が考えることができる最良のことは、groupby =(k、list(g))for groupby = groupby(enumerate(s)、key = lambda x:x [1])]である。 [kのg [0] [0]、g [-1] [0])、グループ化された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]