[英]python regex - optional match
我有一堆串这种味道的东西:
#q1_a1
#q7
基本上#是必须忽略的符号。 #后面是单字母字母和一些数字。 可选地,可以在_
(下划线)后跟随一些字母+数字的组合。
这是我想出的:
>>> pat = re.compile(r"#(.*)_?(.+)?")
>>> pat.match('#q1').groups()
('q1', None)
问题是#q1_a1
格式的字符串。 当我将我制作的东西应用于这样的字符串时:
>>> pat.findall('#q1_f1')
[('q1_f1', '')]
有什么建议么?
正如其他人所说,您的正则表达式越具体,匹配不该匹配的内容的可能性就越小:
In [13]: re.match(r'#([A-Za-z][0-9])(?:_([A-Za-z][0-9]))?', '#q1_a1').groups()
Out[13]: ('q1', 'a1')
In [14]: re.match(r'#([A-Za-z][0-9])(?:_([A-Za-z][0-9]))?', '#q1').groups()
Out[14]: ('q1', None)
笔记:
^
和$
包围正则表达式。 [0-9]
更改为[0-9]+
。 您的“。*”匹配项也带有下划线,因为匹配项很贪心。 更好地创建更具体的正则表达式,以将下划线排除在第一组之外。
正确的正则表达式可能如下所示:
#([a-z][0-9])_?([a-z][0-9])?
但您需要检查它是否适用于您期望的所有数据。
附言 在正则表达式中更具体一些会更好,因为您的假阳性更少。
当您使用.*
,它会尽可能地贪婪地匹配。 尝试:
>>> pat = re.compile(r"#([^_]*)_?(.+)?")
>>> pat.findall('#q1_f1')
[('q1', 'f1')]
同样,最好写一个更具体的表达式:
#([a-z][0-9])(?:_([a-z][0-9]))?
一个不使用正则表达式的简单替代方法:
s = '#q7'
print s[1:].split('_')
# ['q7']
s = '#q1_a1'
print s[1:].split('_')
# ['q1', 'a1']
假设所有字符串都以#
开头。 如果不是这种情况,那么您可以轻松地进行一些验证:
s = '#q1_a1'
if s.startswith('#'):
print s[1:].split('_')
# ['q1', 'a1]
s = 'q1_a1'
if s.startswith('#'):
print s[1:].split('_') # Nothing is printed
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.