在 python 3 regex findall 中匹配多个 OR 条件
match multiple OR conditions in python 3 regex findall
在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" AND "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"之后的出生日期。想知道我该怎么做?谢谢。
您可以使用(?<=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']
您可以匹配 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 后跟单词边界
例如:
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']
在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" AND "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"之后的出生日期。想知道我该怎么做?谢谢。
您可以使用(?<=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']
您可以匹配 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 后跟单词边界
例如:
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']