2017-09-16 109 views
0

比方說,字符串有pattern這樣(\d+)(X|Y|Z)(!|#)?
digits出現=>出現X or Y or Z一個=>! or #並不總是出現。python3解析字符串(含「*」)使用正則表達式

我想解析字符串並想返回列表。

EX1)海峽= 238Z!32Z#11234X
我要回[238Z!32Z#,11234X]

EX2)海峽= 91X92Y93Z
我要回[91X,92Y,93Z]

下面是我的代碼。

# your code goes here 
import re 

p=re.compile('^(\d+)(X|Y|Z)(!|#)?$') 
L=p.findall("238Z!32Z!11234X") 
print(L) 

但我得到空的清單[]
我怎麼了?

+0

你應該從正則表達式中移除'^'和'$'錨點,因爲它們只會在整個字符串匹配一次時才能進行匹配。 – trincot

+0

感謝您的快速評論。 – newbie16

+0

不僅如果你希望它可以工作,你會刪除錨點,但你也需要使用非捕獲替代組。使用're.findall(r'\ d +(?: X | Y | Z)[!#]?',s)',如果XYZ是實際值,也可以使用字符類。 're.findall(r'\ d + [XYZ] [!#]?',s)'。 –

回答

0

不要在正則表達式中使用^$^匹配起始行,$匹配行尾。這意味着你的正則表達式只會匹配開始和結束一行的字符串。

import re 

p=re.compile('(\d+)(X|Y|Z)(!|#)?') 
L=p.findall("238Z!32Z!11234X") 
print(L) 

輸出:

[('238', 'Z', '!'), ('32', 'Z', '!'), ('11234', 'X', '')] 

如果你想不獲得元組,但被匹配,與其整個字符串,請不要使用捕獲組:

p=re.compile('(?:\d+)(?:X|Y|Z)(?:!|#)?') 

輸出:

['238Z!', '32Z!', '11234X'] 
0

首先,^$metacharacters用於匹配字符串的開始和結束(而不是模式)。所以你必須刪除它們,這樣你的正則表達式才能找到所有相應的模式。

其次,findall函數將返回一個組列表,如果您的模式至少包含一個。組由模式中的括號定義。您應該使用non-capturing group(?:...)

import re 

p = re.compile('(?:\d+)(?:X|Y|Z)(?:!|#)?') 
L = p.findall("238Z!32Z!11234X") 
print(L) 
# ['238Z!', '32Z!', '11234X'] 

寫一個正則表達式的另一個建議。如果你想匹配一個字符列表,你不需要(a|b|c),你可以使用[abc]它有相同的含義。

此外,如果要量化單個元素,則不需要使用括號。 (\d+)相當於\d+,您不會再有任何羣組問題了。然後

你的正則表達式將變爲:

\d+[XYZ][!#]? 
0

你不應該使用^$錨,因爲他們需要你的字符串與一個模式完全匹配。

此外,如果你想獲得期望的結果不使用捕捉組:

p=re.compile('\d+[XYZ][!#]?') 

[ '!238Z', '!32Z', '11234X']