【问题标题】:Python Regex matching any order匹配任何订单的 Python 正则表达式
【发布时间】:2017-01-25 10:36:02
【问题描述】:

假设我有日期时间格式

12 September, 2016
September 12, 2016
2016 September, 12

我需要正则表达式,对于上面给出的任何日期格式,它应该始终以相同的顺序返回匹配项

match-1 : 12
match-2 : September
match-3 : 2016

我总是需要相同顺序的结果。

【问题讨论】:

    标签: python regex datetime match


    【解决方案1】:

    您不能切换组顺序,但可以命名您的组:

    (r'(?P<day>[\d]{2})(?:\s|,|\?|$)|(?P<month>[a-zA-Z]+)|(?P<year>[\d]{4})')
    
    • (?P&lt;day&gt;[\d]{2})(?:\s|,|\?|$):匹配一天,可以在python中使用l.group("day")访问

    • (?P&lt;month&gt;[a-zA-Z]+):匹配一个月,可以在python中用l.group("month")访问

    • (?P&lt;year&gt;[\d]{4}):匹配年份,可以在python中使用l.group("year")访问

    例子:

    import re
    
    data = """
    12 September, 2016
    September 12, 2016
    2016 September, 12
    September 17, 2012
    17 October, 2015
    """
    
    rgx = re.compile(r'(?P<day>[\d]{2})(?:\s|,|\?|$)|(?P<month>[a-zA-Z]+)|(?P<year>[\d]{4})')
    
    day = ""
    month = ""
    year = ""
    
    for l in rgx.finditer(data):
            if(l.group("day")):
                    day = l.group("day")
            elif(l.group("month")):
                    month = l.group("month")
            elif(l.group("year")):
                    year = l.group("year")
    
            if(day != "" and month != "" and year != ""):
                    print "{0} {1} {2}".format(day, month, year)
                    day = ""
                    month = ""
                    year = ""
    

    Demo

    【讨论】:

      【解决方案2】:

      下面建议的命名组是一种很好的方法(特别是如果您已经设置了正则表达式),但为了完整起见,这里是如何使用 datetime 模块处理它。

      from datetime import datetime as date
      
      def parse_date(s):
          formats = ["%d %B, %Y",
                     "%B %d, %Y",
                     "%Y %B, %d"]
      
          for f in formats:
              try:
                  return date.strptime(s, f)
              except ValueError:
                  pass
      
          raise ValueError("Invalid date format!")
      
      arr = ["12 September, 2016",
             "September 12, 2016",
             "2016 September, 12",
             "12/9/2016"]
      
      for s in arr:
          dt = parse_date(s)      
          print(dt.year, dt.strftime("%B"), dt.day)
      
      """
      
      2016 September 12
      2016 September 12
      2016 September 12
      Traceback (most recent call last):
        File "C:/Python33/datetest.py", line 22, in <module>
          dt = parse_date(s)
        File "C:/Python33/datetest.py", line 19, in parse_date
          raise ValueError("Invalid date format!")
      ValueError: Invalid date format!
      
      """
      

      有关详细信息,请参阅datetime documentation page

      【讨论】:

      • 您可能想要满足数据不符合这三种格式之一的情况,否则您将面临获得NameError 的风险 - 或者可能甚至更糟,重新使用前一个日期当前不匹配的地方...
      • 酷 - 或者 - 您可以将其包装在类似 here 的函数中
      • 这当然看起来更优雅。我是新来的,我应该继续在我的答案中使用你的想法还是让你自己提交它作为答案更合适?
      • 你很好:)
      【解决方案3】:

      您不能更改组排序。您需要对 3 个模式进行“或”运算,然后通过结果来确定哪个组映射到什么,这应该很简单。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-01
        • 2013-09-22
        • 1970-01-01
        • 2022-12-11
        • 1970-01-01
        • 2020-10-13
        相关资源
        最近更新 更多