正则表达式:将数字与字母分开

4

我有一堆字符串:

"10people"
"5cars"
..

我该如何分割这个字符串?
['10','people']
['5','cars']

这段文本可以包含任意数量的数字和文本。

我在考虑编写某种正则表达式,不过我相信在Python中有更简单的方法。

7个回答

8
使用正则表达式(\d+)([a-zA-Z]+)
import re
a = ["10people", "5cars"]
[re.match('^(\\d+)([a-zA-Z]+)$', x).groups() for x in a]

结果:

[('10', 'people'), ('5', 'cars')]

-1:不适用于像“10cars5toys”这样的字符串。它甚至会抛出异常:“AttributeError: 'NoneType' object has no attribute 'groups'”,尝试在非匹配项上执行列表推导式。 - Tim Pietzcker
1
@Tim:这甚至都没有被指定! - kennytm
1
@Tim:你为什么认为它需要处理这样的字符串?我没有看到OP要求这样做。我也没有看到你要求这样做。这不是正在解决的问题! - SilentGhost
OP写道:“它可以是任意数量的数字和文本”。我似乎不是唯一一个理解它的人。也许OP可以澄清一下。与此同时,我会撤回我的投票。 - Tim Pietzcker

8
>>> re.findall('(\d+|[a-zA-Z]+)', '12fgsdfg234jhfq35rjg')
['12', 'fgsdfg', '234', 'jhfq', '35', 'rjg']

1
我可能会使用 \D 而不是 [a-zA-Z],这将基本上将数字和非数字分开。换句话说,就是 '(\d+|\D+)'。 - Lasse V. Karlsen

3
>>> re.findall("\d+|[a-zA-Z]+","10people")
['10', 'people']

>>> re.findall("\d+|[a-zA-Z]+","10people5cars")
['10', 'people', '5', 'cars']

2
通常情况下,使用正则表达式 /(?<=[0-9])(?=[a-z])|(?<=[a-z])(?=[0-9])/i 进行分割字符串。

对于使用lookaround定义分割点的原则,我表示赞同。然而,在Python中这并不适用,因为根据文档,re.split()从不在空模式匹配上进行分割。 - Tim Pietzcker
所以插入一个分隔符,然后在其上进行拆分:re.sub(r'(?<=\d)(?=\D)|(?<=\D)(?=\d)','!SPLIT_ME!',s).split(r'!SPLIT_ME!') ;) - Alan Moore
即使原帖并不一定需要,对于一般情况仍应+1。 - almcnicoll

0
>>> import re
>>> s = '10cars'
>>> m = re.match(r'(\d+)([a-z]+)', s)
>>> print m.group(1)
10
>>> print m.group(2)
cars

0

如果你和我一样,因为正则表达式太丑陋而绕着弯路,那么这里有一个非正则表达式的方法:

data = "5people10cars"

numbers = "".join(ch if ch.isdigit() else "\n" for ch in data).split()
names = "".join(ch if not ch.isdigit() else "\n" for ch in data).split()

final = zip (numbers, names)

呃。与那个相比,正则表达式是美丽的事物!;-) - Wim
不……太美了……你应该见过我尝试在单个传递中完成这件事的样子,那会涉及动态声明一个类(使用type())并在生成器表达式内实例化它)- 那样对我来说太丑陋了,甚至我也无法继续下去。 - jsbueno

0
借鉴jsbueno的想法,使用str.translate,然后跟随split:
import string

allchars = ''.join(chr(i) for i in range(32,256))
digExtractTrans = string.maketrans(allchars, ''.join(ch if ch.isdigit() else ' ' for ch in allchars))
alpExtractTrans = string.maketrans(allchars, ''.join(ch if ch.isalpha() else ' ' for ch in allchars))

data = "5people10cars"
numbers = data.translate(digExtractTrans).split()
names = data.translate(alpExtractTrans).split()

您只需要创建一次翻译表,然后随时调用翻译和分割函数即可。


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