2011-02-10 15 views
23

Pythonで複数のグループを返すのが混乱しています。私の正規表現はこれです:Python RegEx複数のグループ

lun_q = 'Lun:\s*(\d+\s?)*' 

そして、私の文字列は、私はマッチしたオブジェクトを返し、その後、グループを見てみたいが、すべてはそれが最後の数(258)ことを示して

s = '''Lun:      0 1 2 3 295 296 297 298'''` 

次のとおりです。など0,1,2,3,4

r.groups() 
(u'298',) 

なぜそれが戻っていないグループ?

+3

私はあなたが直接(http://www.regular-expressions.info/captureall [繰り返しグループのキャプチャ]と呼ばれているを参照してください何だと思います.html) - または線に沿って '定量/繰り返し捕獲グループのすべての一致にアクセスする'。 [この同様の答え](http://stackoverflow.com/a/3537914/611007)のjavascriptを参照してください。確かに分かりませんが*** Pythonの正規表現の味でサポートされていないようです***。 [関連するpython拡張リクエスト](http://bugs.python.org/issue7132)と[関連する質問](http://stackoverflow.com/q/15908085/611007) – n611x007

答えて

20

あなたの正規表現には1組のカッコ(1つのキャプチャグループ)しか含まれていないので、あなたのマッチでは1つのグループしか得られません。キャプチャグループ(+または*)で反復演算子を使用すると、グループが繰り返されるたびにグループが上書きされます。つまり、最後の一致のみがキャプチャされます。ここにあなたの例では

、あなたは正規表現との組み合わせで、.split()を使用してオフにおそらくより良いです:

lun_q = 'Lun:\s*(\d+(?:\s+\d+)*)' 
s = '''Lun: 0 1 2 3 295 296 297 298''' 

r = re.search(lun_q, s) 

if r: 
    luns = r.group(1).split() 

    # optionally, also convert luns from strings to integers 
    luns = [int(lun) for lun in luns] 
+3

're.match()'を選んでください。 're.split()'は自明ではありません。 – smci

2

別のアプローチは、あなたのデータを検証して、より多くのを使用するようにあなたが持っている正規表現を使用することですマッチイテレータを使用して抽出する各アイテムをターゲットとする特定の正規表現です。

import re 
s = '''Lun: 0 1 2 3 295 296 297 298''' 
lun_validate_regex = re.compile(r'Lun:\s*((\d+)(\s\d+)*)') 
match = lun_validate_regex.match(s) 
if match: 
    token_regex = re.compile(r"\d{1,3}") 
    match_iterator = token_regex.finditer(match.group(1)) 
    for token_match in match_iterator: 
     #do something brilliant 
+0

print re.findall( '\ d'、s) –

6

時には正規表現なしで簡単です。

>>> s = '''Lun: 0 1 2 3 295 296 297 298''' 
>>> if "Lun: " in s: 
...  items = s.replace("Lun: ","").split() 
...  for n in items: 
...  if n.isdigit(): 
...   print n 
... 
0 
1 
2 
3 
295 
296 
297 
298 
1

あなたがそのような0,1,2,3,4として出力を探している場合など は以下である最も単純な答え。

印刷re.findall( '\ dの'、s)は