如何用Python正则表达式从多格式OCR文本中提取日期及报错解决
解决方案:提取OCR文本中的多种日期格式并修复正则错误
嘿,我来帮你搞定这个问题!你遇到的AttributeError根源有两个:一是你的正则表达式只覆盖了dd-mm-yyyy这一种日期格式,其他你提到的格式(比如带月份名称、斜杠分隔的)都匹配不到,导致re.search返回None,调用.group()自然会报错;二是你代码里写了re.search(..., 'text'),这里的'text'是固定字符串,而不是你DataFrame里的df['Text']列内容。
下面是分步解决的方案:
1. 编写能覆盖所有目标日期格式的正则表达式
针对你列出的所有日期格式:07-June-2018、08/3/17、30-04-2018、03/june/19、sep 29,2018、24may'19,我们可以写一个通用的正则来匹配它们:
date_pattern = r""" \b(?: # 格式1: dd-Month-yyyy / dd-month-yyyy \d{1,2}-(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)-\d{4}| # 格式2: dd/mm/yy / dd/mm/yyyy / d/m/yy / d/m/yyyy \d{1,2}/\d{1,2}/\d{2,4}| # 格式3: dd-mm-yyyy / d-mm-yyyy \d{1,2}-\d{1,2}-\d{4}| # 格式4: month dd,yyyy / Month dd,yyyy (?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\s\d{1,2},\d{4}| # 格式5: ddmonth'yy / ddMonth'yy \d{1,2}(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)'\d{2} )\b """
这个正则用非捕获分组(?:...)整合所有格式,同时支持月份的全称和缩写,后续会通过参数忽略大小写,让匹配更灵活。
2. 修复代码错误并批量处理DataFrame
我们可以用pandas的apply方法逐行处理Text列,同时添加判断避免None的情况:
import re import pandas as pd # 读取你的OCR文本CSV文件 df = pd.read_csv("你的OCR文本文件.csv") # 定义日期匹配函数 def extract_date(text): date_pattern = r""" \b(?: \d{1,2}-(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)-\d{4}| \d{1,2}/\d{1,2}/\d{2,4}| \d{1,2}-\d{1,2}-\d{4}| (?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\s\d{1,2},\d{4}| \d{1,2}(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)'\d{2} )\b """ match = re.search(date_pattern, text, flags=re.IGNORECASE | re.VERBOSE) if match: return match.group(0) # 返回匹配到的完整日期字符串 else: return None # 没有匹配到返回None # 对Text列应用函数,生成新的日期提取列 df['Extracted_Date'] = df['Text'].apply(extract_date) # 查看处理结果 print(df[['Text', 'Extracted_Date']].head())
3. 额外优化:统一日期格式(可选)
如果你需要把提取到的日期统一转换成标准格式(比如yyyy-mm-dd),可以用dateutil库的解析工具:
先安装依赖库:
pip install python-dateutil
然后修改提取函数:
from dateutil import parser def extract_and_standardize_date(text): date_pattern = r""" \b(?: \d{1,2}-(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)-\d{4}| \d{1,2}/\d{1,2}/\d{2,4}| \d{1,2}-\d{1,2}-\d{4}| (?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\s\d{1,2},\d{4}| \d{1,2}(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)'\d{2} )\b """ match = re.search(date_pattern, text, flags=re.IGNORECASE | re.VERBOSE) if match: date_str = match.group(0) try: # 解析日期并转换成标准格式 return parser.parse(date_str).strftime('%Y-%m-%d') except: return date_str # 解析失败返回原字符串 else: return None
这样就能把各种零散格式的日期统一成标准格式,方便后续的数据分析或存储。
内容的提问来源于stack exchange,提问作者marton mar suri
相关产品推荐
相关产品推荐

