2012-11-18 71 views
4

我想匹配字符串的不同部分,並將它們存儲在單獨的變量中供以後使用。例如,Python re:在變量中存儲多個匹配

string = "bunch(oranges, bananas, apples)" 
rxp = "[a-z]*\([var1]\, [var2]\, [var3]\)" 

讓我有

var1 = "oranges" 
var2 = "bananas" 
var3 = "apples" 

喜歡的東西是什麼re.search()不會,但對於同一場比賽中的多個不同部分。

編輯:列表中的水果數量事先不知道。應該把這個問題放在這個問題上。

回答

3

這就是re.search所做的。只要使用捕獲組(括號)來訪問,是由某些子模式以後匹配的東西:

>>> import re 
>>> m = re.search(r"[a-z]*\(([a-z]*), ([a-z]*), ([a-z]*)\)", string) 
>>> m.group(0) 
'bunch(oranges, bananas, apples)' 
>>> m.group(1) 
'oranges' 
>>> m.group(2) 
'bananas' 
>>> m.group(3) 
'apples' 

還要注意,我用了一個原始字符串,以避免雙反斜線。

如果bunch中的「變量」數量可能會有所不同,則說明您有問題。大多數正則表達式引擎無法捕獲可變數量的字符串。然而,在這種情況下,你可以逃脫這樣的:

>>> m = re.search(r"[a-z]*\(([a-z, ]*)\)", string) 
>>> m.group(1) 
'oranges, bananas, apples' 
>>> m.group(1).split(', ') 
['oranges', 'bananas', 'apples'] 
1

的正則表達式,你可以使用match()功能做你想要什麼,並使用羣體,讓您的結果。此外,不要分配給單詞string,因爲這是一個內置函數(即使它已被棄用)。對於你的榜樣,如果你知道有每次都是一樣的水果中,它看起來像這樣:

import re 
input = "bunch(oranges, bananas, apples)" 
var1, var2, var3 = re.match('bunch\((\w+), (\w+), (\w+)\)', input).group(1, 2, 3) 

在這裏,我用了\w特殊序列,它匹配任何字母數字字符或下劃線,如解釋the documentation

如果你事先不知道水果的數量,你可以使用兩個正則表達式調用,一個是獲取水果列出的字符串的最小部分,擺脫「束」和圓括號,然後finditer來提取水果名稱:

import re 
input = "bunch(oranges, bananas, apples)" 
[m.group(0) for m in re.finditer('\w+(,)?', re.match('bunch\(([^)]*)\)', input).group(1))] 
+0

是啊,>字符串<只是爲了說明,我不使用它。同樣,每次都沒有相同數量的水果,但是我明白了你的意思。謝謝! – Arish

+0

檢查編輯是否有另一種方法從字符串中提取未知數量的項目。 – acjay

1

不要。每次你使用var1,var2等,你實際上都想要一個列表。不幸的是,這是沒有辦法使用findall收集在一個列表分組的任意數,但你可以使用這樣一個黑客:

import re 
lst = [] 
re.sub(r'([a-z]+)(?=[^()]*\))', lambda m: lst.append(m.group(1)), string) 
print lst # ['oranges', 'bananas', 'apples'] 

注意這不僅對這個具體的例子,但也可爲任何數量的的子串。

4

如果你願意,你可以使用groupdict匹配項存儲在詞典:

regex = re.compile("[a-z]*\((?P<var1>.*)\, (?P<var2>.*)\, (?P<var3>.*)") 
match = regex.match("bunch(oranges, bananas, apples)") 
if match: 
    match.groupdict() 

#{'var1': 'oranges', 'var2': 'bananas', 'var3': 'apples)'}