我有没有更简洁的正则表达式可以实现我的想法?

3
我需要仅接受数字值输入,范围为0至100,可以是整数或者浮点数,但是最多只能有两位小数,并编写正则表达式以检查这些条件。
例如,我希望它可以接受以下值:
0(min), 0.1, 1, 11, 11.1, 11.11, 100(max).

但不包括以下任何一项:

-1, 100.1, 111, 1+1, .1, etc.

迄今为止,我想到了^\d?\d+(\.\d\d?)?$,但它有很多问题。

刚才在提交时,在类似问题侧边栏中看到了这个链接,它似乎有解决方案("^((?:|0|[1-9]\d?|100)(?:\.\d{1,2})?)$"),除了它还接受100.01100.99。 除此之外,这是一个非常小的问题,它应该可以工作。

但是有没有人知道如何修复那个特定的部分?


1
你是如何从用户那里获取输入的?通过命令行还是某种UI界面? - jspurim
使用 Python 的 input()。 - Terrornado
4个回答

5

根据输入方式的不同,检查数字值可能更容易和更快速。

def acceptable(str_val):
    try:
        return 0 <= float(str_val) <= 100
    except ValueError:
        return False

acceptable('1.11')
# True

acceptable('abc')
# False

acceptable('100.0')
# True

acceptable('100.1')
# False

+1 我同意,尽管这不完全是 OP 想要的,但我认为它更清晰和/或更符合 Python 风格... - Joe Iddon
+1,这是一个有趣的解决方案,正如Joe所说,这将更清晰和更符合Pythonic。如果我没有将我的问题限制在纯正则表达式上,并且如果我可以接受多个答案,我也完全会这样做。这真的很有帮助,谢谢。 - Terrornado

5

100是唯一的真正例外,所以应该相当简单:

^(?:100|\d{1,2}(?:\.\d{1,2})?)$

https://regex101.com/r/Rr0gs4/1

编辑:还允许 100.0100.00

^(?:100(?:\.00?)?|\d{1,2}(?:\.\d{1,2})?)$


不确定是否是必需的。但这与01或02.22匹配。 - jrook
2
可能不希望匹配 01。您可以通过将 \d{1,2} 更改为 [1-9]?\d 来解决这个问题。 - janos
1
为了避免前导0的问题,您可以在\d{1,2}之前添加(?!0\d)。或者您可以将第一个\d{1,2}更改为[1-9]?\d - Casimir et Hippolyte
好的观点,尽管我不确定原帖作者是否真的想排除那些模式。如果得到确认,我将编辑答案。 - CAustin
编辑了答案,包括这一点。 - CAustin
显示剩余2条评论

1
这个测试包含所有可接受的输入以及示例中不允许的输入。
import re

regex = re.compile(r'^(100(\.00?)?|((\d|[1-9]\d)(\.\d\d?)?))$')

def matches(s):
    print('Testing', s)
    return bool(regex.search(s))

for i in range(0, 101):
    s = str(i)
    assert matches(s), 'no match for %s' % s

for i in range(0, 100):
    for j in range(0, 100):
        s = '{i}.{j}'.format(i=i, j=j)
        assert matches(s), 'no match for %s' % s

        # Special case for .0N (e.g., 1.01, 1.02, etc)
        if j == 0:
            for k in range(0, 10):
                s = '{i}.0{k}'.format(i=i, k=k)
                assert matches(s), 'no match for %s' % s

non_matches = ('-1', '100.1', '111', '1+1', '.1', 'abc')
for s in non_matches:
    assert not matches(s), 'unexpected match for %s' % s

0
尝试使用以下代码:re.match(r'(\d{,2}\.?\d*)?|(100)?', 'string_goes_here')

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