【问题标题】:how does the OR operator (|) works in regular expression?OR 运算符 (|) 在正则表达式中如何工作?
【发布时间】:2019-09-26 15:31:44
【问题描述】:

想在正则表达式匹配中使用 or 运算符(|),但它不起作用。将错误消息作为“不支持的操作数”。有人可以在这里看看吗?

两个都试过了|和“或”,但都不起作用。

import re

date = "02.29.2001"
date29 = "((02)\.(0[1-9]|[12][0-9]))"
date28 = "((02)\.(0[1-9]|[12][0-8]))"
res = re.search((date28 | date29)+("\.(\d+)"),date)

如果我只使用 date29 那么它匹配,但是当我将它更改为上面的时,它不匹配。

【问题讨论】:

  • 你试过date28+"|"+date29吗?
  • 您可以结合date28 + "|" + date29 来构建您的搜索正则表达式。您要使用此 +("\.(\d+)")?? 搜索哪个部分。我还建议您使用在线沙箱来预先构建您的正则表达式,例如this one

标签: python regex python-2.7


【解决方案1】:

您正在将 Python 语法(or boolean 和 | 按位 OR 运算符)与正则表达式语法混合。

虽然正则表达式确实使用| 来分隔替代模式,但正则表达式中使用的语法与 Python 运算符不同且分开。你不能随意将两者结合起来。正则表达式语法通过字符串传递给 re 模块函数,而不是作为 Python 表达式。

这行得通:

either = r"({}|{})\.(\d+)".format(date28, date29)
res = re.search(either, date)

因为正则表达式模式使用正则表达式语法first组合成单个字符串。

注意这里没有意义使用date28,因为date28可以匹配的所有东西,date29也可以匹配。此外,date2802.19.(有效日期为 2 月)不匹配。

如果您想从“已标记”组件构建正则表达式,我建议您使用re.VERBOSE 标志,这会导致正则表达式(包括换行符)中的空格被忽略,并添加对使用# ... cmets 的支持。要匹配空格,请使用显式类,例如 [ ][\n]\s 等。我也经常将其与显式组名结合使用。

例如你的表达式可以写成:

february_date = re.compile(
    r"""
    (
        02\.     # month, always February
        (        # Leap year
            0[1-9]      # first 9 days
            |
            [12][0-9]   # remainder from 10 to 29
        )
        |
        02\.
        (        # regular year
            0[1-9]      # first 9 days
            |
            [12][0-8]   # remainder 10-18, 20-28
        )
    )
    \.(\d+)   # The year
    """, flags=re.VERBOSE)
res = february_date.search(date)

这种格式还使您更容易看到您在任一模式的开头匹配02\.,这是相当多余的,当然上面的模式仍然存在[12][0-8]与@冗余的问题987654340@,实际上与 2 月 19 日不匹配。

就我个人而言,我只是使用\d{2}\.\d{2}\.\d{4},然后使用datetime.strptime() 来验证匹配的文本实际上是一个有效的日期。构建一个正则表达式来验证日期是一项艰巨的任务,根本不值得努力。

例如,您尝试构建的模式并未告诉您 2001 年不是闰年,因此 02.29.2001 不是有效日期。但是尝试使用datetime.strptime() 解析它会引发异常,告诉您这不是有效日期:

>>> from datetime import datetime
>>> date = '02.29.2001'
>>> datetime.strptime(date, "%m.%d.%Y")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/_strptime.py", line 458, in _strptime
    datetime_date(year, 1, 1).toordinal() + 1
ValueError: day is out of range for month

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-30
    • 2011-01-03
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    • 2011-12-22
    • 2013-11-18
    • 2014-08-24
    相关资源
    最近更新 更多