将字符串分割成整数部分和字符串部分的最佳方法是什么?

3

我有一个字符串,像这样 "11547QSD"。我想把它分成两部分 "11547" 和 "QSD"。我得到了一个提示,使用 isnumeric() 函数。我在下面提供一个概述,请建议我最好的拆分方法。

 str1 = "11547QSD"    # is a valid string (in my context)
 str2 = "ABC98765"    # is a valid string
 str3 = "111ABC111"   # is not a valid string

 if str1.isvalid():
    str1_int = str1.integer_part()
    str1_str = str1.string_part()

提前感谢。


3
我建议您采用“朴素”的方法来解决它,除非您习惯于命令式编程并想使用Python技巧。遍历它,找到从 isnumeric()isalpha() 的变化点,确保只有一个点,并在那里将其拆分。 - Elazar
4个回答

5

您可以使用带有命名组的正则表达式。

基本上,您首先创建正则表达式(我创建了两个,一个用于数字优先的情况,另一个用于字母优先的情况)。然后您检查输入是否匹配。如果匹配,则在结果匹配对象上调用groupdict()以获取类似{'digits':'11547', 'letters':'QSD'}的字典。然后您只需使用它(我打印了它)。

遵循上述建议的完整示例:

>>> import re
>>> checks = [
    re.compile(r'^(?P<digits>\d+)(?P<letters>\D+)$'),
    re.compile(r'^(?P<letters>\D+)(?P<digits>\d+)$'),
]
>>> inputs = ['11547QSD', 'ABC98765', '111ABC111']
>>> for item in inputs:
    for check in checks:
        if check.match(item):
            print('Digits are {digits}, letters are {letters}'.format(
                **check.search(item).groupdict()
            ))
            break
    else:
        print('%s is incorrect' % (item,))


Digits are 11547, letters are QSD
Digits are 98765, letters are ABC
111ABC111 is incorrect

简化版

如果您理解以上内容,可以缩短代码并创建结果字典(匹配字符串 - 结果组),如下:

>>> from itertools import product
>>> {item: check.search(item).groupdict()
     for (item, check) in product(inputs, checks) if check.match(item)}
{'ABC98765': {'digits': '98765', 'letters': 'ABC'},
'11547QSD': {'digits': '11547', 'letters': 'QSD'}}

注意:

我使用了元字符\d\D。第一个基本上意味着“数字”,第二个意味着“非数字”。有关它们的详细信息,请在这里查看。


0
from string import ascii_letters, digits
s_int, s_str = sorted([s.strip(ascii_letters), s.strip(digits)])
is_valid = s in {s_int+s_str, s_str+s_int}

0

主要是为了好玩:

ss  = ["11547QSD", "ABC98765", "111ABC111"]

fmt = r'\A(?P<full>{0}{1})\Z'
ps  = [r'(?P<digits>\d+)', r'(?P<letters>[A-Z]+)']

fs  = [fmt.format(*sorted(ps, reverse = b)) for b in [False, True]]
rs  = [re.compile(f) for f in fs]
ms  = filter(None, (r.search(s) for s in ss for r in rs))
gds = [m.groupdict() for m in ms]

for gd in gds:
    print gd

# Output:
# {'digits': '11547', 'full': '11547QSD', 'letters': 'QSD'}
# {'digits': '98765', 'full': 'ABC98765', 'letters': 'ABC'}

0

我认为正则表达式应该是最好的解决方案,以下是一个例子:

import re
re.split(r'(\d+|\(|\))', '11547QSD')


这将返回一个列表,其中第一项为空引号:['','11547','QSD']。我不熟悉正则表达式,但是你如何在表达式中删除它而不是在末尾添加[1:] - Ryan Saxe

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