2017-09-16 106 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']