【问题标题】:Python Regular expression not returning as expectedPython正则表达式未按预期返回
【发布时间】:2016-01-27 04:35:42
【问题描述】:

我无法理解这个正则表达式的输出。我正在使用以下正则表达式在文本中查找日期:

^(?:(1[0-2]|0?[1-9])-(3[01]|[12][0-9]|0?[1-9])|(3[01]|[12][0-9]|0?[1-9])-(1[0-2]|0?[1-9]))-(?:[0-9]{2})?[0-9]{2}$

它似乎正确匹配文本中的模式,但我对返回值感到困惑。

对于这个测试字符串:

TestString = "10-20-2015"

它返回这个:

[('10', '20', '', '')]

如果我把 () 放在整个正则表达式周围,我会得到这个返回:

[('10-20-2015', '10', '20', '', '')]

我希望它只返回完整的日期字符串,但它似乎将结果分解,我不明白为什么。将我的正则表达式包装在 () 中会返回完整的日期字符串,但它也会返回 4 个额外的值。

如何使它只匹配完整的日期字符串而不是字符串的一小部分?

从我的控制台:

Python 3.4.2 (default, Oct  8 2014, 10:45:20) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> pattern = "^(?:(1[0-2]|0?[1-9])-(3[01]|[12][0-9]|0?[1-9])|(3[01]|[12][0-9]|0?[1-9])-(1[0-2]|0?[1-9]))-(?:[0-9]{2})?[0-9]{2}$"
>>> TestString = "10-20-2015"
>>> re.findall(pattern, TestString, re.I)
[('10', '20', '', '')]
>>> pattern = "(^(?:(1[0-2]|0?[1-9])-(3[01]|[12][0-9]|0?[1-9])|(3[01]|[12][0-9]|0?[1-9])-(1[0-2]|0?[1-9]))-(?:[0-9]{2})?[0-9]{2}$)"
>>> re.findall(pattern, TestString, re.I)
[('10-20-2015', '10', '20', '', '')]
>>> 
>>> TestString = "10--2015"
>>> re.findall(pattern, TestString, re.I)
[]
>>> pattern = "^(?:(1[0-2]|0?[1-9])-(3[01]|[12][0-9]|0?[1-9])|(3[01]|[12][0-9]|0?[1-9])-(1[0-2]|0?[1-9]))-(?:[0-9]{2})?[0-9]{2}$"
>>> re.findall(pattern, TestString, re.I)
[]

根据回复,这是我的答案:((?:(?:1[0-2]|0[1-9])-(?:3[01]|[12][0- 9]|0[1-9])|(?:3[01]|[12][0-9]|0[1-9])-(?:1[0-2]|0[1- 9]))-(?:[0-9]{2})?[0-9]{2})

【问题讨论】:

    标签: python regex


    【解决方案1】:

    每个() 都是一个捕获组,(1[0-2]|0?[1-9]) 捕获10(3[01]|[12][0-9]|0?[1-9]) 捕获20,依此类推。当您将所有内容包围在() 中时,它会排在另一个() 之前并匹配所有内容。您可以忽略一个名为non-captured group 的捕获组,使用(?:) 而不是()

    【讨论】:

    • 谢谢!我知道我错过了一些东西。修改为此,它现在正在工作: ((?:(?:1[0-2]|0[1-9])-(?:3[01]|[12][0-9]|0[1 -9])|(?:3[01]|[12][0-9]|0[1-9])-(?:1[0-2]|0[1-9]))-( ?:[0-9]{2})?[0-9]{2})
    【解决方案2】:

    我们可以使用最重要的 re 函数之一 - search() 来做到这一点。这个函数扫描一个字符串,寻找这个 RE 匹配的任何位置。

    import re
    
    text = "10-20-2015"
    
    date_regex = '(\d{1,2})-(\d{1,2})-(\d{4})'
    
    """ 
    \d in above pattern stands for numerical characters [0-9].
    The numbers in curly brackets {} indicates the count of numbers permitted.
    Parentheses/round brackets are used for capturing groups so that we can treat 
    multiple characters as a single unit.
    
    """
    
    search_date = re.search(date_regex, text)
    
    # for entire match
    print(search_date.group())
    # also print(search_date.group(0)) can be used
     
    # for the first parenthesized subgroup
    print(search_date.group(1))
     
    # for the second parenthesized subgroup
    print(search_date.group(2))
     
    # for the third parenthesized subgroup
    print(search_date.group(3))
     
    # for a tuple of all matched subgroups
    print(search_date.group(1, 2, 3))
    

    上述每个打印语句的输出:

    10-20-2015
    10
    20
    2015
    ('10', '20', '2015')
    

    希望这个答案能消除你的疑问:-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      • 1970-01-01
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      • 2014-04-28
      相关资源
      最近更新 更多