Python解析字符串,已知结构

2024-10-03 06:25:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我必须用已知的结构解析一个简单的字符串列表,但是我发现它不必要地笨拙。 我觉得我错过了一个诀窍,也许是一些简单的正则表达式可以让这件事变得微不足道?

这个字符串指的是未来的年/月数,我想把它变成十进制年份。

通用格式:“aYbM”

其中a是年数,b是月数,可以是int,两者都是可选的(以及它们的标识符)

测试用例:

5Y3M == 5.25
5Y == 5.0
6M == 0.5
10Y11M = 10.91666..
3Y14M = raise ValueError("string '%s' cannot be parsed" %input_string)

到目前为止,我的尝试涉及到字符串拆分,虽然它们确实产生了正确的结果,但还是相当麻烦:

^{pr2}$

Tags: 字符串列表string格式测试用例标识符结构int
3条回答

你可以使用regex模式

(?:(\d+)Y)?(?:(\d+)M)?

也就是说

^{pr2}$

当用于

re.match(r'(?:(\d+)Y)?(?:(\d+)M)?', text).groups()

groups()方法返回分组括号内的匹配部分。^如果组不匹配,则返回{}。例如

In [220]: re.match(r'(?:(\d+)Y)?(?:(\d+)M)?', '5Y3M').groups()
Out[220]: ('5', '3')

In [221]: re.match(r'(?:(\d+)Y)?(?:(\d+)M)?', '3M').groups()
Out[221]: (None, '3')

import re
def parse_aYbM(text):
    a, b = re.match(r'(?:(\d+)Y)?(?:(\d+)M)?', text).groups()
    if a == b == None:
        raise ValueError('input does not match aYbM')
    a, b = [int(item) if item is not None else 0 for item in (a, b)]
    return a + b/12.0

tests = [
('5Y3M', 5.25),
('5Y', 5.0),
('6M', 0.5),
('10Y11M', 10.917),
('3Y14M', 4.167),
]

for test, expected in tests:
    result = parse_aYbM(test)
    status = 'Failed'
    if abs(result - expected) < 0.001:
        status = 'Passed'
    print('{}: {}  > {}'.format(status, test, result))

收益率

Passed: 5Y3M  > 5.25
Passed: 5Y  > 5.0
Passed: 6M  > 0.5
Passed: 10Y11M  > 10.9166666667
Passed: 3Y14M  > 4.16666666667

注意,如果parse_aYbM的输入与模式不匹配,会发生什么情况还不清楚。对于上面的代码,不匹配将引发ValueError

In [227]: parse_aYbM('foo')
ValueError: input does not match aYbM

但部分匹配可能返回一个值:

In [229]: parse_aYbM('0Yfoo')
Out[229]: 0.0

不熟悉python regex,但可以尝试类似 (?<year>[^Y])\D(?<month>[^M]*)\D可能就是这样。在

您可以使用re.findall

>>> def parse(m):
    s = 0
    j = re.findall(r'\d+Y|\d+M', m)
    for i in j:
        if 'Y' in i:
            s += float(i[:-1])
        if 'M' in i:
            s += float(i[:-1])/12
    print(s)


>>> parse('5Y')
5.0
>>> parse('6M')
0.5
>>> parse('10Y11M')
10.916666666666666
>>> parse('3Y14M')
4.166666666666667

相关问题 更多 >