【问题标题】:match multiple OR conditions in python 3 regex findall在 python 3 regex findall 中匹配多个 OR 条件
【发布时间】:2020-02-19 01:54:05
【问题描述】:

在 python 3 中:

这是应监控个人资产的外国资产控制办公室清单

https://www.treasury.gov/ofac/downloads/sdn.csv

他们的很多出生数据(最后一列,逗号分隔)就像

DOB 23 Jun 1959; alt. DOB 23 Jun 1958

DOB 1959; alt. DOB 1958

我正在尝试使用以下代码捕获关键字“DOB”和“alt.DOB”之后的所有生日:

   if len(x.split(';')) > 0:
        if len(re.findall('DOB (.*)', x.split(';')[0])) > 0:
            new = re.findall('DOB | alt. DOB (.*)', x.split(';')[0])[0]
            print(new)

            try:
                print(datetime.strptime(new, '%d %b %Y'))
                return datetime.strptime(new, '%d %b %Y')
            except:
                return None

但代码仅在“DOB”之后获取出生日期,但不包括“alt. DOB”之后的出生日期。想知道我该怎么做?谢谢。

【问题讨论】:

    标签: regex python-3.x findall


    【解决方案1】:

    您可以匹配 DOB 并使用捕获组作为日期部分。对于日期部分,天数和月份可以是可选的,后跟匹配的 4 位数字。

    日期部分模式不验证日期本身,它使匹配更加具体。

    \bDOB ((?:(?:3[01]|[12][0-9]|0?[1-9]) [A-Za-z]+ )?\d{4})\b
    

    说明

    • \bDOB 匹配字面上的字边界
    • (捕获组1
      • (?:非捕获组
        • (?:3[01]|[12][0-9]|0?[1-9]) [A-Za-z]+ 匹配一个数字 1-31 和 1+ 个字符 A-Za-z
      • )? 关闭群组并将其设为可选
      • \d{4}匹配4位数字
    • )\b关闭第 1 组,后跟单词边界

    Regex demo | Python demo

    例如:

    import re
    
    regex = r"\bDOB ((?:(?:3[01]|[12][0-9]|0?[1-9]) [A-Za-z]+ )?\d{4})\b"
    test_str = ("DOB 23 Jun 1959; alt. DOB 23 Jun 1958\n"
        "DOB 1959; alt. DOB 1958")
    
    print(re.findall(regex, test_str))
    

    输出

    ['23 Jun 1959', '23 Jun 1958', '1959', '1958']
    

    【讨论】:

    • 嗨@第四只鸟,如果我想捕捉“ DOB Jun 1958”,我该如何修改正则表达式?谢谢。
    • "regex = r"\bDOB ((?:(?:3[01]|[12][0-9]|0?[1-9]) ?:[A-Za -z]+ )?\d{4})\b"" 这只会返回 ['1959', '1958']。
    • @Chubaka 在这种情况下,您可以将月份的数字部分设为可选regex101.com/r/yTzDmm/1
    【解决方案2】:

    您可以使用(?<=DOB\s)[\s[a-zA-Z0-9]+]*

       (?<=DOB\s)  = Negative look-behind assertion. This matches string (which is to its right) only if the string preceded by letters DOB followed by a space
       [\s[a-zA-Z0-9]+]* = Match space followed by letters of numbers multiple times
    

    例子:

    items=['DOB 23 Jun 1959; alt. DOB 23 Jun 1958', 'DOB 1959; alt. DOB 1958']
    for item in items:
        print(re.findall(r'(?<=DOB\s)[\s[a-zA-Z0-9]+]*',item))
    

    输出

    ['23 Jun 1959', '23 Jun 1958']
    ['1959', '1958']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-31
      • 2014-09-23
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      • 2019-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多