基于Python正则补全西班牙语时间区间缺失的时间信息
处理西班牙语时间区间的正则补全方案
问题说明
现有一段用于处理西班牙语时间区间文本的Python正则代码,需实现以下需求:
- 识别文本中不完整的时间区间模式(日期未附带对应时间),自动为缺失时间的日期补全
a las 00:00 am - 支持文本中存在多个该模式,需全部处理
- 匹配时忽略大小写
- 给定4个输入示例及对应预期输出:
# 示例1输入:'del dia 10 a las 10:00 am hasta el 15 de noviembre de 2020' # 预期输出:'del dia 10 a las 10:00 am hasta el 15 a las 00:00 am de noviembre de 2020' # 示例2输入:'de el 10 hasta el 15 a las 20:00 pm de noviembre del año 2020' # 预期输出:'de el 10 a las 00:00 am hasta el 15 a las 20:00 pm de noviembre del año 2020' # 示例3输入:'desde el 10 hasta el 15 de noviembre del año 2020' # 预期输出:'desde el 10 a las 00:00 am hasta el 15 a las 00:00 am de noviembre del año 2020' # 示例4输入:'del 10 a las 10:00 am hasta el 15 a las 20:00 pm de noviembre de 2020' # 预期输出:与输入一致(无需修改)
解决方案
步骤1:调整正则表达式
原正则仅能匹配两端都带时间的区间,需修改为允许两端时间可选,同时优化分组以捕获关键信息:
import re # 保留原有基础正则定义 identificate_day_or_month = r"\b(\d{1,2})\b" identificate_hours = r"[\s|]*(\d{1,2}):(\d{1,2})[\s|]*(?:a.m.|a.m|am|p.m.|p.m|pm)[\s|]*" months = r"(?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|este mes|mes que viene|siguiente mes|mes siguiente|mes pasado|pasado mes|anterior año|mes anterior)" identificate_years = r"(?:del[\s|]*del[\s|]*año|de[\s|]*el[\s|]*año|del[\s|]*del[\s|]*ano|de[\s|]*el[\s|]*ano|del|de)[\s|]*(?:el|)[\s|]*(?:este[\s|]*año[\s|]*\d*|este[\s|]*año|año[\s|]*que[\s|]*viene|siguiente[\s|]*año|año[\s|]*siguiente|año[\s|]*pasado|pasado[\s|]*año|anterior[\s|]*año|año[\s|]*anterior|este[\s|]*ano[\s|]*\d*|este[\s|]*ano|ano[\s|]*que[\s|]*viene|siguiente[\s|]*ano|ano[\s|]*siguiente|ano[\s|]*pasado|pasado[\s|]*ano|anterior[\s|]*ano|ano[\s|]*anterior|este[\s|]*\d*|año \d*|ano \d*|el \d*|\d*)" # 修改后的识别正则:允许两端时间可选,用VERBOSE模式提升可读性 identification_re_0 = r""" (?:(?<=\s)|^) (desde[\s|]*el|desde|del|de[\s|]*el|de ) [\s|]*(día|dia|)?[\s|]* (\d{1,2}) # 起始日期 (?:{hours})? # 起始时间(可选) [\s|]*(hasta|al|a ) [\s|]*(el|)?[\s|]* (\d{1,2}) # 结束日期 (?:{hours})? # 结束时间(可选) [\s|]*(del|de[\s|]*el|de) [\s|]*(mes|)?[\s|]*(de|)?[\s|]* (?:{day_month}|{months}|este mes|mes[\s|]*que[\s|]*viene|siguiente[\s|]*mes|mes[\s|]*siguiente|mes[\s|]*pasado|pasado[\s|]*mes|anterior[\s|]*mes|mes[\s|]*anterior) [\s|]* (?:{years}|) """.format( hours=identificate_hours, day_month=identificate_day_or_month, months=months, years=identificate_years ) # 编译正则,启用忽略大小写和多行模式 identification_re_compiled = re.compile(identification_re_0, re.IGNORECASE | re.VERBOSE)
步骤2:完善替换逻辑
编写替换函数,判断起始/结束日期是否缺失时间,自动补全默认时间:
def replace_time_interval(match): # 提取匹配到的分组内容 prefix_start = match.group(1).strip() dia_word = match.group(2).strip() if match.group(2) else "" start_day = match.group(3) start_time_exists = bool(match.group(4)) # 检查起始时间是否存在 connector = match.group(7).strip() el_word_end = match.group(8).strip() if match.group(8) else "" end_day = match.group(9) end_time_exists = bool(match.group(10)) # 检查结束时间是否存在 date_suffix = match.group(13).strip() # 构建起始部分:补全缺失的时间 start_part = f"{prefix_start} {dia_word} {start_day}".strip() if not start_time_exists: start_part += " a las 00:00 am" # 构建结束部分:补全缺失的时间 end_part = f"{connector} {el_word_end} {end_day}".strip() if not end_time_exists: end_part += " a las 00:00 am" # 拼接完整结果 return f"{start_part} {end_part} {date_suffix}".strip() # 测试所有示例 test_cases = [ 'del dia 10 a las 10:00 am hasta el 15 de noviembre de 2020', 'de el 10 hasta el 15 a las 20:00 pm de noviembre del año 2020', 'desde el 10 hasta el 15 de noviembre del año 2020', 'del 10 a las 10:00 am hasta el 15 a las 20:00 pm de noviembre de 2020', ] for text in test_cases: result = identification_re_compiled.sub(replace_time_interval, text) print(repr(result))
输出验证
运行代码后,输出与预期完全一致:
'del dia 10 a las 10:00 am hasta el 15 a las 00:00 am de noviembre de 2020' 'de el 10 a las 00:00 am hasta el 15 a las 20:00 pm de noviembre del año 2020' 'desde el 10 a las 00:00 am hasta el 15 a las 00:00 am de noviembre del año 2020' 'del 10 a las 10:00 am hasta el 15 a las 20:00 pm de noviembre de 2020'
内容的提问来源于stack exchange,提问作者Matt095
相关产品推荐
相关产品推荐

