【问题标题】:substring replacement based on condition -python基于条件的子字符串替换 -python
【发布时间】:2021-12-06 09:23:41
【问题描述】:

我有一个数据框,其中有一列包含字符串(句子)。该字符串有许多驼峰式缩写。还有一本字典详细介绍了这些缩写及其各自的长格式。

例如: 字典:{'ShFrm':'Shortform', 'LgFrm':'Longform' ,'Auto':'Automatik'} 数据框列有这样的文本:(为简单起见,每个列表条目是数据框中的一行) ['ShFrmLgFrm 应该自动替换','Auto', 'AutoLgFrm']

如果我只是使用字典替换,所有替换都是正确的,除了在第一个文本中自动转换为“自动”。

我尝试在带有条件的字典的键值中使用正则表达式,只有在它之前有空格/开始 pf 字符串/小字母并且在它之后有大写字母/空格/句子结尾时才替换单词:'( ?:^|[a-z])ShFrm(?:[^A-Z]|$)',但它也替换了中间字符串前后的字符。

您能否帮我修改正则表达式模式,使其仅在它之前有小写字母/之前是单词/空格的开头并且之后有大写字母/单词结尾/空格之后才匹配缩写,并且只替换中间词,而不替换前后字符

【问题讨论】:

    标签: python regex


    【解决方案1】:

    您需要从字典键构建基于交替的正则表达式,并使用 lambda 表达式作为替换参数。

    见下面Python demo

    import re
    d = {'ShFrm':'Shortform', 'LgFrm':'Longform' ,'Auto':'Automatik'}
    col = ['ShFrmLgFrm should be replaced Automatically','Auto', 'AutoLgFrm']
    rx = r'(?:\b|(?<=[a-z]))(?:{})(?=[A-Z]|\b)'.format("|".join(d.keys()))
    # => (?:\b|(?<=[a-z]))(?:ShFrm|LgFrm|Auto)(?=[A-Z]|\b)
    print([re.sub(rx, lambda x: d[x.group()], v) for v in col])
    # => ['ShortformLongform should be replaced Automatically', 'Automatik', 'AutomatikLongform']
    

    在 Pandas 中,您可以这样使用它:

    df[col] = df[col].str.replace(rx, lambda x: d[x.group()], regex=True)
    

    请参阅regex demo

    【讨论】:

    • 谢谢。但是,如果字典键是独立的单词,则此正则表达式模式只会匹配字典键。它不会将第一和第三字符串中的 ShFrm 和 LgFrm 替换为其长形式。是否可以通过在 rx 中定义的模式中添加更多条件来解决?
    • @RituGahir 好的,我实现了您的要求,请参阅更新后的答案。
    【解决方案2】:

    您可以使用前瞻函数来匹配主表达式之后的组,而不将其包含在结果中。

    (?<=\b|[a-z])(ShFrm|LgFrm|Auto)(?=[A-Z]|\b)
    

    这完全符合您的要求。虽然pythonre只支持固定宽度的正向lookbehind,我们可以改为负向lookbehind

    rx=r"(?<![A-Z])(ShFrm|LgFrm|Auto)(?=[A-Z]|\b)"
    re.findall(rx,"['ShFrmLgFrm should be replaced Automatically','Auto', 'AutoLgFrm']")
    

    输出:['ShFrm', 'LgFrm', 'Auto', 'Auto', 'LgFrm']

    【讨论】:

    • 你的模式is invalid in Python
    • @WiktorStribiżew 只需改为消极的后视
    • 但是,这在数字或下划线之后仍然匹配,不确定 OP 是否提到了这些情况。
    猜你喜欢
    • 2021-01-22
    • 2015-02-02
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    • 2021-12-06
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多