如何用Python将字符串按照数字和字母分割?

5

我有一些包含可选数字和字母的字符串,例如'01a'、'b'和'02'。这些字符串始终由两部分组成,左边是数字,右边是字母。我想把这些字符串拆分开来,以便分别获取数字和字母。如何定义mySplit才能得到这个结果?

>>> map(mySplit, ['01123absd', 'bsdf', '02454'])

[('01123', 'absd'), (None, 'bsdf'), ('02454', None)]

1
它是否总是格式化数字然后是字母? - thegrinner
总是只有两个部分吗? - LucasB
是的,总会有两个部分。 - msampaio
5个回答

6

您可以使用正则表达式实现此功能。我们需要的是:

  • 以0个或多个数字开头的字符串,
  • 以0个或多个字母结尾的字符串。

请注意,regex将创建命名组,它也被编译为更有效地在每次调用时使用。

import re
regex = re.compile("^(?P<numbers>\d*)(?P<letters>\w*)$")

def myFunction(entry):
  (numbers, letters) = regex.search(entry).groups()
  return (numbers or None, letters or None)

map(myFunction, ['01123absd', 'bsdf', '02454'])

最后一行的调用将产生以下输出:
[('01123', 'absd'), (None, 'bsdf'), ('02454', None)]

4

jramirez的答案类似,只是稍微简短:

def myFunction(s):
    return (''.join(c for c in s if c.isdigit()) or None, 
            ''.join(c for c in s if c.isalpha()) or None)

使用 filter 可以更简洁地实现相同的功能:

def myFunction(s):
    return (''.join(filter(str.isdigit, s)) or None, 
            ''.join(filter(str.isalpha, s)) or None)

输出:

print(*map(myFunction, ['01123absd', 'bsdf', '02454', '012abc345def']))
('01123', 'absd') (None, 'bsdf') ('02454', None) ('012345', 'abcdef')

这是一个很棒的解决方案,因为它比使用正则表达式要快得多。 - misantroop

3
这里可以使用正则表达式:

import re

def myFunction(numbers_and_letters):
    m = re.match(r"([a-z]*)([0-9]*)", numbers_and_letters)
    return tuple(v == "" and None or v for v in m.groups())

应该不使用星号,因为两种排序都不必要。 - deinonychusaur
是的,你说得对。我还需要将''改为None。 - apai
return tuple(v == "" and None or v for v in m.groups()) - deinonychusaur

2

如果您不想使用正则表达式,这是一个解决方案:

def split_num_str(my_str):
    num = [x for x in my_str if x.isdigit()]
    num = "".join(num)

    if not num:
        num = None

    my_str = [x for x in my_str if x.isalpha()]
    my_str = ''.join(my_str)

    if not my_str:
        my_str = None

    return num, my_str

m = map(split_num_str, ['01123absd', 'bsdf', '02454'])
print m

结果 = [('01123', 'absd'), (None, 'bsdf'), ('02454', None)]

这是一个包含三个元组的列表,每个元组都有两个值。第一个值是一个字符串,第二个值可以是字符串或空值。

0
import re


def myFunction(t):
    m = re.match(r"([a-z]*)([0-9]*)", t)
    x,y = m.groups()
    if x=='': x= None    
    if y=='': y= None    
    return ((x,y))

for s in ['01123absd', 'bsdf', '02454']:
    print myFunction(s)

产生:

(None, '01123')
('bsdf', None)
(None, '02454')

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