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

正则表达式优化:匹配不以‘aa’开头的‘cc dd’子串

问题解决:匹配不以"aa"开头的"cc dd"子串并仅替换目标内容

需求

使用Python的re模块匹配文本中不以“aa”开头的“cc dd”子串,同时保留对“ee”的匹配替换逻辑。当前正则表达式会匹配包含“cc dd”的整段前缀内容,不符合预期,需要仅匹配“cc dd”本身。

当前代码

import re

s = 'bb cc dd ee\naa : bb cc dd ee\n11 cc dd ee'
pp = re.compile(r'(?P<n1>ee)|(?P<n2>^(?!aa\b).*\bcc dd\b)', re.MULTILINE)

def _rep(x):
    print(x.groupdict())
    return [f'<{k}>' for k, v in x.groupdict().items() if v is not None][0]

rr = pp.sub(_rep, s)
print(rr)

当前运行结果

# print(x.groupdict())
    {'n1': None, 'n2': 'bb cc dd'}
    {'n1': 'ee', 'n2': None}
    {'n1': 'ee', 'n2': None}
    {'n1': None, 'n2': '11 cc dd'}
    {'n1': 'ee', 'n2': None}

# print(rr)
    <n2> <n1>
    aa : bb cc dd <n1>
    <n2> <n1>

期望结果

# print(x.groupdict())
    {'n1': None, 'n2': 'cc dd'}
    {'n1': 'ee', 'n2': None}
    {'n1': 'ee', 'n2': None}
    {'n1': None, 'n2': 'cc dd'}
    {'n1': 'ee', 'n2': None}

# print(rr)
    bb <n2> <n1>
    aa : bb cc dd <n1>
    11 <n2> <n1>

修正方案

修改正则表达式,让n2捕获组仅匹配“cc dd”本身,同时通过正向后查确保该子串所在行不以“aa”开头:

import re

s = 'bb cc dd ee\naa : bb cc dd ee\n11 cc dd ee'
# 调整正则,使用正向后查限定行开头,仅捕获目标子串"cc dd"
pp = re.compile(r'(?P<n1>ee)|(?P<n2>(?<=^(?!aa\b).*?)\bcc dd\b)', re.MULTILINE)

def _rep(x):
    print(x.groupdict())
    return [f'<{k}>' for k, v in x.groupdict().items() if v is not None][0]

rr = pp.sub(_rep, s)
print(rr)

修正说明

  • 原正则中(?P<n2>^(?!aa\b).*\bcc dd\b)会匹配从行开头到“cc dd”的全部内容,导致替换时丢失了“bb”“11”等前缀。
  • 修正后的(?P<n2>(?<=^(?!aa\b).*?)\bcc dd\b):
    1. (?<=^(?!aa\b).*?) 是正向后查,确保当前“cc dd”所在的行开头不是“aa”,且仅匹配到“cc dd”之前的内容(不捕获);
    2. \bcc dd\b 精准匹配目标子串,并放入n2捕获组,确保替换时仅修改“cc dd”本身。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:39:32