循环遍历Python正则表达式匹配

99

我想把一个看起来像这样的字符串转换成:

ABC12DEF3G56HIJ7

进入

12 * ABC
3  * DEF
56 * G
7  * HIJ

我想使用正则表达式匹配构建正确的循环集。问题的关键在于代码必须完全通用,因为我不能假设 [A-Z] 片段的长度或者 [0-9] 片段的长度。


4
''.join("%s * %s\n" % (n, w) for w, n in re.findall(r'(?i)([a-z]+)(\d+)', input_string)) - jfs
4个回答

150

Python的re.findall应该适合您的需求。

演示示例

import re

s = "ABC12DEF3G56HIJ7"
pattern = re.compile(r'([A-Z]+)([0-9]+)')

for (letters, numbers) in re.findall(pattern, s):
    print(numbers, '*', letters)

94

如果您的数据集很大,最好使用re.finditer,因为它可以减少内存消耗(findall()返回所有结果的列表,finditer()逐个查找它们)。

import re

s = "ABC12DEF3G56HIJ7"
pattern = re.compile(r'([A-Z]+)([0-9]+)')

for m in re.finditer(pattern, s):
    print m.group(2), '*', m.group(1)

如果我没记错的话,这个例子的最后一行应该是 print m.group(2), '*', m.group(1) 才能符合 OP 的期望输出。 我相信 m.group(0) 是“完整”的匹配——即 ABC12、DEF3、G56、HIJ7。 - DaveL17
@DaveL17 你说得对,谢谢。我在回答时没有多想,现在已经修复了。 - Mithril
3
这种方法的好处在于,您可以通过名称访问命名组,而不是通过正则表达式中的位置进行访问(如果模式在正则表达式中移动,则可能会更改位置)。 - Carl G
为什么这样更好? - Jann Poppinga
@Jann Poppinga 减少内存使用。findall 获取所有结果,finditer 逐个获取。 - Mithril

1
一个更简单的一句话可以是
print(re.sub(r"([A-Z]+)(\d+)", r'\2 * \1\n', s))

0
另一个选项是使用re.sub()从捕获的组中创建所需的字符串:
import re
s = 'ABC12DEF3G56HIJ7'
for x in re.sub(r"([A-Z]+)(\d+)", r'\2 * \1,', s).rstrip(',').split(','):
    print(x)

12 * ABC
3 * DEF
56 * G
7 * HIJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接