python – 将由字母和数字组成的字符串拆分为多个部分

我有一个字符串,由字符串和数字(​​整数或浮点数)的交替字符串组成,它们具有任意长度,我希望将它分成几个部分,每个部分都有最大可能的大小,这样一个部分将由一个字符串或一个(表示一个)数字的字符串.

我不需要考虑特殊形式的数字,如指数,十六进制等;只是简单的浮点或整数.

几个例子:

>>> split("")
()
>>> split("p")
('p',)
>>> split("2")
('2',)
>>> split("a2b3")
('a', '2', 'b', '3')
>>> split("a2.1b3")
('a', '2.1', 'b', '3')
>>> split("a.1b3")
('a', '.1', 'b', '3')

但是,以下调用应该引发一些错误:

>>> split(3)
>>> split("a0.10.2")
>>> split("ab.c")

我的第一次尝试是使用re.split.但是,这种尝试很幼稚,如果我写这些字母,它就不会保存分隔符:

>>> re.split("[a-z]", "a.1b3")
['', '.1', '3']

我的第二次尝试是使用itertools.groupby.问题在于它并不关心数字的形式,例如:

>>> islowalpha = labmda s: str.isalpha(s) and str.islower(s)
>>> [''.join(g) for _, g in itertools.groupby("a0.10.2b", islowalpha)]  # should raise
['a', '0.10.2', 'b']

注意:我不关心输出的形式,只要它是可迭代的.

注意:我已阅读this,但我无法使解决方案适应我的问题.主要区别在于我需要只允许可接受的数字,而不是简单的数字和点列表.

最佳答案

import re

def split_gen(x):
    for f, s in re.findall(r'([\d.]+)|([^\d.]+)', x):
        if f:
            float(f)
            yield f
        else:
            yield s

def split(x):
    '''
    >>> split("")
    ()
    >>> split("p")
    ('p',)
    >>> split("2")
    ('2',)
    >>> split("a2b3")
    ('a', '2', 'b', '3')
    >>> split("a2.1b3")
    ('a', '2.1', 'b', '3')
    >>> split("a.1b3")
    ('a', '.1', 'b', '3')
    >>> split(3)
    Traceback (most recent call last):
    ...
    TypeError: expected string or buffer
    >>> split("a0.10.2")
    Traceback (most recent call last):
    ...
    ValueError: could not convert string to float: '0.10.2'
    >>> split("ab.c")    
    Traceback (most recent call last):
    ...
    ValueError: could not convert string to float: '.'
    '''
    return tuple(split_gen(x))

if __name__ == '__main__':
    import doctest
    doctest.testmod()
点赞