【问题标题】:Is there a cleaner Regex expression for what I have in mind?对于我的想法,是否有更简洁的正则表达式?
【发布时间】:2017-11-08 20:05:21
【问题描述】:

我只需要接受输入为数字值0 to 100integersfloats,其中 ma​​x two 包含小数位,并编写一个正则表达式来检查这些条件。

例如,我希望它接受以下值:

0(min), 0.1, 1, 11, 11.1, 11.11, 100(max).

但不是任何一个:

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

到目前为止,我想出了^\d?\d+(\.\d\d?)?$,只是它有很多问题。

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

但是有人知道如何修补那个特定的位吗?

【问题讨论】:

  • 你是如何从用户那里得到这个输入的?通过命令行或某种 ui?
  • 使用python输入()

标签: python regex python-3.x


【解决方案1】:

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
  • 可能不希望匹配01。您可以通过将 \d{1,2} 更改为 [1-9]?\d 来解决此问题
  • 为了防止出现前导0的问题,可以在\d{1,2}前加上(?!0\d)。或者你可以把\d{1,2}(第一个)改成[1-9]?\d
  • 好点,虽然我不确定 OP 是否真的想要排除这些模式。如果我们得到确认,我会编辑答案。
  • 即使 00.01-09.99 被接受为带有前导零的值也可以。然而,这只是一个小问题,它不允许 100.00。有没有办法包含 100.00 但不包含 100.01-100.99?
【解决方案2】:

根据您获取输入的方式,简单地检查数值可能更容易、更快捷。

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 想要的,但我认为它更清晰和/或更 Pythonic...
  • +1,我的问题的有趣解决方案,正如乔所说,这会更清晰,更 Pythonic。如果我没有将我的问题限制为纯粹的正则表达式,并且如果我可以接受多个答案,我也完全会这样做。这真的很有帮助,谢谢。
【解决方案3】:

这会测试所有允许的输入和示例的非允许输入。

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

【讨论】:

    【解决方案4】:

    试试这个re.match(r'(\d{,2}\.?\d*)?|(100)?', 'string_goes_here')

    【讨论】:

      猜你喜欢
      • 2012-11-15
      • 2012-07-20
      • 2011-06-22
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多