验证字符串是否仅由数字范围组成Python 2.7

时间:2018-06-27 13:50:51

标签: python regex python-2.7 range

我需要验证字符串在Python2.7中是否是格式正确的数字范围,我的意思是我们在选择要打印的某些特定页面时使用的范围,例如:

1,3,5-7, 10, 15 - 20

我希望它接受破折号和逗号周围的空格,因为通常人们倾向于在以下范围内使用空格:

我没有太多运气尝试过正则表达式。在Python 3中有一个re.fullmatch显然仅在整个字符串与模式匹配时才匹配,在Python 2.7中不存在,但是我尝试在Python 2中使用this way withch显然可以正常工作,但是我的正则表达式似乎是错误的。我尝试了许多不同的正则表达式,但它们都以一种或另一种方式失败了,最后一个正则表达式在行首允许使用错误的字符(这仅用于逗号,还没有破折号):

^\d+$|(\d+)(\s?)(,{1})(\s?)(\d+)

我不必为此使用正则表达式,但是很高兴知道如何使用正则表达式来解决此问题。

5 个答案:

答案 0 :(得分:3)

如果您使用正则表达式,也许这符合您的要求:

^\d+(?: *- *\d+)?(?:, *\d+(?: *- *\d+)?)*$

说明

  • ^断言行的开头
  • \d+匹配一个或多个数字
  • (?:非捕获组
    • *- *\d+匹配零个或多个空格,后跟一个连字符,一个或多个空格和一个或多个数字
  • )?关闭非捕获组并将其设置为可选
  • (?:非捕获组
    • , *\d+匹配一个逗号,零个或多个空格以及一个或多个数字
    • (?:非捕获组
      • *- *\d+匹配零个或多个空格,后跟连字符,零个或多个空格字符以及一个或多个数字
    • )?关闭非捕获组并将其设置为可选
  • )*关闭非捕获组,并将其重复零次或多次
  • $声明行的结尾

Demo

答案 1 :(得分:1)

我不会理会正则表达式。

def verify(s):
    last = 0
    for r in s.replace(' ', '').split(','):
        # A single integer...
        try:
            last = int(r)
            continue
        except ValueError:
            pass

        # ... or a hyphen-separated pair of increasing integers
        try:
            x, y = r.split("-")
            if not (last < x <= y):
                return False
            last = y
        except ValueError:
            return False

    return True

这还可以确保值按排序顺序出现,而正则表达式则无法执行。

答案 2 :(得分:1)

由于无论如何最终都需要对其进行解析,因此使用解析作为验证更加直接。许多Python库也使用这种方法,例如JSON。它避免了重复的逻辑(1.验证,2。解析),允许更具表现力的错误消息,并且通常更容易。

要解析单个文字,例如54,请对其进行拆分并转换开始/停止值。如果数字不是有效的整数,则会自动引发1 - 3

ValueError

您可以使用它来聚合多个文字的页面,例如def page_range(literal): """ Convert a single page literal into a sequence of pages :raises ValueError: if literal does not denote a valid page range """ start, sep, stop = literal.partition('-') # '1 -3' => '1 ', '-', '3'; ' 4' => ' 4', '', '' if not start: # may want to raise an error for empty page literals return [] if not sep: # no '-' in literal, just the start return [int(start)] # sep is present, literal is a range of pages return list(range(int(start), int(stop) + 1)) 。通过使用异常,可以为无效的文字的部分引发错误:

4, 1-3

答案 3 :(得分:1)

我只是用逗号分割,然后用连字符分割,然后控制每个连字符分隔的范围不超过整数。以下函数返回一个生成器,该生成器在验证语法后返回每个范围的1或2个整数的列表:

def parse(string):
    ranges = re.split(r'\s*,\s*', string.strip())  # split on comma ignoring spaces
    for i in ranges:
        limits = re.split(r'\s*-\s*', i)   # optionaly splits on hyphen
        if len(limits) > 2:                # one max
            raise ValueError('More than one hyphen in a range ({})'
                     .format(i))
        if any([ re.match('[0-9]+', num) == None for num in limits ]): # only integers allowed
            raise ValueError('A page number is not an integer ({})'
                     .format(num))
        yield [ int(num) for num in limits ]

这将很乐意忽略任何空格或制表符,但仍可确保语法正确

答案 4 :(得分:0)

您可以使用搜索字符串.document.querySelectorAll("a[onclick='javascript:doSubmit('Edit-1');']")(1).Click 查找空白,数字范围(任意数量的空白,例如'^(?:\s+|\d+\s*-\s*\d+|,|\d+)*$'1 - 3都匹配),逗号,或数字。

问题在于它不需要逗号来分隔每个出现的位置,因此1-3是有效的,并且它不在乎是否重复逗号所以1 2 3 4也有效。如果您关心这些事情,那么这对您来说将无法正常工作。