如何使用正则表达式分隔字符串中的数字和字符,如“30M1000N20M”

时间:2013-02-27 01:50:06

标签: regex python

我正在尝试将[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>

3 个答案:

答案 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')