You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按原字符串顺序提取并打印匹配多正则模式的子串?

时间表达式提取与顺序输出实现

核心思路

要按原字符串中出现顺序提取目标片段,不能用原框架中“匹配到一个就跳过后续”的逻辑,而是要收集所有正则的匹配结果,记录每个结果的起始位置,最后按位置排序输出,同时处理可能的重叠匹配问题。

正则模式构建

先定义通用时间匹配模式,覆盖各种时间格式(如19、19:30、19 30、19pm、19:30 am等):

TIME_PATTERN = r'\d{1,2}(?:[:\s]\d{1,2})?(?:\s*(?:a\.?m\.?|p\.?m\.?))?'

再基于此构建三个目标正则,每个正则捕获需要输出的完整片段:

  1. 模式1:匹配包含两个时间的关联表达式(如entre las 19hs y las 20 30),捕获前后两个时间片段
  2. 模式2:匹配带am/pm标识的时间表达式(如las 19 15 pm)
  3. 模式3:匹配带特定前缀的单个时间表达式(如antes de las 14 30)

完整代码实现

import re

# 通用时间匹配模式
TIME_PATTERN = r'\d{1,2}(?:[:\s]\d{1,2})?(?:\s*(?:a\.?m\.?|p\.?m\.?))?'

# 定义所有正则模式及对应描述
REGEX_PATTERNS = [
    # 模式1:匹配双时间关联表达式
    (
        re.compile(
            r'(entre\s+(?:las|la)\s+' + TIME_PATTERN + r'(?:\s+de\s+la\s+(?:tarde|noche|mañana))?)\s+(y\s+(?:las|la)\s+' + TIME_PATTERN + r'(?:\s+de\s+la\s+(?:tarde|noche|mañana))?)',
            re.IGNORECASE
        ),
        "first regex pattern"
    ),
    # 模式2:匹配带am/pm的时间表达式
    (
        re.compile(
            r'((?:las|la)\s+' + TIME_PATTERN + r'\s*(?:a\.?m\.?|p\.?m\.?)(?:\s+de\s+la\s+(?:tarde|noche|mañana))?)',
            re.IGNORECASE
        ),
        "second regex pattern"
    ),
    # 模式3:匹配带前缀的单个时间表达式
    (
        re.compile(
            r'((?:a\s+eso\s+de|a\s+esas\s+de|despues\s+de|antes\s+de|hasta|tipo|desde|apartir\s+de|de|a)\s+(?:las|la)\s+' + TIME_PATTERN + r'(?:\s+de\s+la\s+(?:tarde|noche|mañana))?)',
            re.IGNORECASE
        ),
        "third regex pattern"
    )
]

def extract_time_expressions(input_text):
    matches = []
    # 遍历所有正则,收集所有匹配项及位置
    for pattern, desc in REGEX_PATTERNS:
        for match in pattern.finditer(input_text):
            # 模式1有两个捕获组,分别添加
            if len(match.groups()) == 2:
                start1, _ = match.span(1)
                matches.append( (start1, match.group(1), desc) )
                start2, _ = match.span(2)
                matches.append( (start2, match.group(2), desc) )
            else:
                start, _ = match.span(1)
                matches.append( (start, match.group(1), desc) )
    
    # 按起始位置排序,保证出现顺序
    matches.sort(key=lambda x: x[0])
    
    # 过滤重叠匹配,保留先出现的完整片段
    filtered_matches = []
    last_end = -1
    for start, text, desc in matches:
        current_end = start + len(text)
        if start >= last_end:
            filtered_matches.append( (text, desc) )
            last_end = current_end
    
    return filtered_matches

# 测试示例(替换input_text为任意示例字符串即可)
if __name__ == "__main__":
    input_text = "quizas seria mejor ir de 06 00 am a 11 59 ya que me gusta viajar a esas horas"
    results = extract_time_expressions(input_text)
    for text, desc in results:
        print(f'"{text}"   <--- was extracted by the {desc}')

测试说明

  • 替换input_text为任意示例字符串,即可得到符合要求的输出
  • 代码通过finditer获取每个匹配的起始位置,排序后保证输出顺序与原字符串一致
  • 过滤逻辑避免了重叠匹配的重复输出,确保每个时间片段只被提取一次

内容的提问来源于stack exchange,提问作者Matt095

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 11:24:37