5

我正在尝试将这些字符串中的[0-9]和分开:[A-Z]

100M
20M1D80M
20M1I79M
20M10000N80M

我尝试使用 Pythonre模块,以下是我使用的代码:

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

此正则表达式适用于仅包含一个匹配项但不包含多组匹配项的字符串。我如何使用正则表达式来处理它?

4

3 回答 3

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']
于 2013-02-27T03:41:16.333 回答
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']
于 2013-02-27T03:02:33.977 回答
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')
于 2013-02-27T03:42:47.990 回答