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

如何避免多重负前瞻的正则灾难性回溯及Pandas字符串处理

Pandas字符串条件添加与排除处理

需求

当DataFrame的Ruling列字符串满足以下条件时,在末尾添加section 22:

  • 字符串包含personal information
  • 字符串不包含s. 26、s. 29、s. 33、s. 22、s. 32中的任意一项

示例数据

import pandas as pd
df = pd.DataFrame({
    'Order': ['Order90-098','OrderF14-47', 'OrderF13-43', 'Order56-090', 'Order90-098', 'Order78-897'],
    'Ruling': ['foo','personal information', 's. 26 personal information', 'personal information s. 33', 'personal information s. 67', 'personal s. 32 information']})

期望结果

df = pd.DataFrame({
    'Order': ['Order90-098','OrderF14-47', 'OrderF13-43', 'Order56-090', 'Order90-098', 'Order78-897'],
    'Ruling': ['foo','personal information section 22', 's. 26 personal information', 'personal information s. 33', 'personal information s. 67 section 22', 'personal s. 32 information']})

问题分析

你之前尝试的多重负前瞻正则因结构冗余导致灾难性回溯,而析取式写法未覆盖全局匹配逻辑,导致排除条件失效。

解决方案

方案1:修正正则表达式

将所有排除项整合到单个负前瞻中,确保检查整个字符串是否包含任何排除项,同时精准匹配目标内容:

import re

df['Ruling'] = df['Ruling'].apply(
    lambda x: re.sub(
        r'^(?!.*(s\. (?:22|26|29|32|33))).*(personal information.*)$',
        r'\1 section 22',
        x,
        flags=re.IGNORECASE
    )
)
  • ^(?!.*(s\. (?:22|26|29|32|33))):负前瞻规则,确保字符串中不存在任何指定的s. xx项
  • (personal information.*)$:捕获包含personal information的完整内容,用于替换时追加后缀

方案2:Pandas条件判断(可读性更强)

避开正则复杂度,直接用Python字符串判断结合Pandasapply实现,逻辑更直观:

exclude_terms = {'s. 26', 's. 29', 's. 33', 's. 22', 's. 32'}

def add_section(text):
    if 'personal information' in text:
        # 检查是否存在任何排除项
        if not any(term in text for term in exclude_terms):
            return text + ' section 22'
    return text

df['Ruling'] = df['Ruling'].apply(add_section)

这种方法无需处理正则匹配的边界问题,代码维护成本更低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:45:56