我正在尝试将[0-9]
和[A-Z]
分隔成以下字符串:
100M
20M1D80M
20M1I79M
20M10000N80M
我尝试使用Python re
模块,以下是我使用的代码:
>>>import re
>>>num_alpha = re.compile('(([0-9]+)([A-Z]))+')
>>>str1="100M"
>>>n_a_match = num_alpha.match(str1)
>>>n_a_match.group(2), n_a_match.group(3)
100,M #just what I want
>>>str1="20M10000N80M"
>>>n_a_match = num_alpha.match(str1)
>>>n_a_match.groups()
('80M', '80', 'M') #only the last one, how can I get the first two?
#expected result ('20M','20','M','10000N','10000','N','80M','80','M')
此正则表达式适用于仅包含一个匹配但不包含多个匹配组的字符串。如何使用正则表达式处理它?</ p>
答案 0 :(得分:3)
尝试使用split
方法:
>>> str1="20M10000N80M"
>>> num_alpha = re.compile('(([0-9]+)([A-Z]))')
>>> l = num_alpha.split(str1)
>>> l
['', '20M', '20', 'M', '', '10000N', '10000', 'N', '', '80M', '80', 'M', '']
请注意,我删除了正则表达式中的+
。
要删除空字符串,列表生成器:
>>> l_without_empty = [x for x in l if x != '']
['20M', '20', 'M', '10000N', '10000', 'N', '80M', '80', 'M']
编辑:
或者,如评论所述:
>>> l_without_empty = [x for x in l if x]
['20M', '20', 'M', '10000N', '10000', 'N', '80M', '80', 'M']
答案 1 :(得分:3)
我建议使用re.findall
。如果您打算迭代结果,而不是构建列表,则可以使用re.finditer
代替。这是一个如何工作的例子:
>>> re.findall("(([0-9]+)([A-Z]))", "20M10000N80M")
[('20M', '20', 'M'), ('10000N', '10000', 'N'), ('80M', '80', 'M')]
如果你不想要组合数字+字母字符串,你可以从匹配中删除外括号,然后得到单独的部分:
>>> re.findall("([0-9]+)([A-Z])", "20M10000N80M")
[('20', 'M'), ('10000', 'N'), ('80', 'M')]
或者,如果您根本不想要元组(并且您不需要担心格式错误的输入,例如连续多个字母的字符串),您可以将模式更改为交替,并获取值一个接一个:
>>> re.findall("([0-9]+|[A-Z])", "20M10000N80M")
['20', 'M', '10000', 'N', '80', 'M']
答案 2 :(得分:2)
另一种选择是转而使用re.findall
:
>>> string = "20M10000N80M"
>>> groups = re.findall(r'((\d+)(\D+))', string)
[('20M', '20', 'M'), ('10000N', '10000', 'N'), ('80M', '80', 'M')]
所以,你可以看到不同的组作为元组返回,然后,如果你真的想要它作为你呈现的元组 - 你可以展平它:
>>> from itertools import chain
>>> tuple(chain.from_iterable(groups))
('20M', '20', 'M', '10000N', '10000', 'N', '80M', '80', 'M')