首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用以regex表达式作为键的dict的多个regex替换

使用以regex表达式作为键的dict的多个regex替换
EN

Stack Overflow用户
提问于 2021-02-19 00:21:37
回答 2查看 522关注 0票数 4

我希望使用多个正则表达式对字符串进行多个替换。我还想在一次传递中进行替换,以避免创建多个字符串实例。

假设我想在下面进行替换,同时避免多次使用re.sub(),无论是显式的还是循环的:

代码语言:javascript
运行
复制
import re

text = "local foals drink cola"
text = re.sub("(?<=o)a", "w", text)
text = re.sub("l(?=a)", "co", text)

print(text) # "local fowls drink cocoa"

我找到的最接近的解决方案是从替换目标字典编译一个正则表达式,然后使用lambda函数用字典中的值替换每个匹配的目标。但是,这种方法在使用元字符时不起作用,从而从本例中的正则表达式中删除了所需的功能。

首先,让我用一个没有元字符的示例演示一下:

代码语言:javascript
运行
复制
import re

text = "local foals drink cola"

subs_dict = {"a":"w", "l":"co"}
subs_regex = re.compile("|".join(subs_dict.keys()))
text = re.sub(subs_regex, lambda match: subs_dict[match.group(0)], text)

print(text) # "coocwco fowcos drink cocow"

现在注意到,将所需的元字符添加到字典键中会产生一个KeyError:

代码语言:javascript
运行
复制
import re

text = "local foals drink cola"

subs_dict = {"(?<=o)a":"w", "l(?=a)":"co"}
subs_regex = re.compile("|".join(subs_dict.keys()))
text = re.sub(subs_regex, lambda match: subs_dict[match.group(0)], text)

>>> KeyError: "a"

原因是sub()函数正确地找到了表达式"(?<=o)a"的匹配项,因此现在必须在字典中找到它才能返回它的替换,但是match.group(0)提交的字典查找值是对应的匹配字符串"a"。它也不适合在字典中搜索match.re (即生成匹配的表达式),因为它的值是从字典键(即"(?<=o)a|l(?=a)")编译的整个不相交的表达式。

编辑:如果有人从看到使用lambda函数实现的would解决方案尽可能接近我的原始文件中受益,那么它的工作方式如下:

代码语言:javascript
运行
复制
import re

text = "local foals drink cola"

subs_dict = {"(?<=o)a":"w", "l(?=a)":"co"}
subs_regex = re.compile("|".join("("+key+")" for key in subs_dict))

group_index = 1
indexed_subs = {}
for target, sub in subs_dict.items():
    indexed_subs[group_index] = sub
    group_index += re.compile(target).groups + 1

text = re.sub(subs_regex, lambda match: indexed_subs[match.lastindex], text)

print(text) # "local fowls drink cocoa"
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-19 00:29:38

如果要使用的表达式不匹配空字符串(如果要替换,这是一个有效的假设),则可以在对表达式进行|之前使用组,然后检查找到匹配的组:

(exp1)|(exp2)|(exp3)

或者命名组,这样您就不必计算子表达式中的子组了。

替换函数可以查看哪个组匹配,并从列表中选择替换。

我想出了这个实现:

代码语言:javascript
运行
复制
import re
def dictsub(replacements, string):
    """things has the form {"regex1": "replacement", "regex2": "replacement2", ...}"""
    exprall = re.compile("|".join("("+x+")" for x in replacements))
    gi = 1
    replacements_by_gi = {}
    for (expr, replacement) in replacements.items():
        replacements_by_gi[gi] = replacement
        gi += re.compile(expr).groups + 1


    def choose(match):
        return replacements_by_gi[match.lastindex]

    return re.sub(exprall, choose, string)


text = "local foals drink cola"
print(dictsub({"(?<=o)a":"w", "l(?=a)":"co"}, text))

打印local fowls drink cocoa

票数 3
EN

Stack Overflow用户

发布于 2021-02-19 00:38:08

您可以通过将键保持为预期的匹配并将替换和regex存储在嵌套的dict中来做到这一点。考虑到您希望匹配特定的字符,这个定义应该可以工作。

代码语言:javascript
运行
复制
subs_dict = {"a": {'replace': 'w', 'regex': '(?<=o)a'}, 'l': {'replace': 'co', 'regex': 'l(?=a)'}}
subs_regex = re.compile("|".join([subs_dict[k]['regex'] for k in subs_dict.keys()]))
re.sub(subs_regex, lambda match: subs_dict[match.group(0)]['replace'], text)

'local fowls drink cocoa'
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66270091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档