Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中编写多个替换?_Python_Regex - Fatal编程技术网

如何在python中编写多个替换?

如何在python中编写多个替换?,python,regex,Python,Regex,我有一个包含键、值对的python字典,我想用相应的值替换字典中键的字符串中的一些单词 我尝试了一些在线代码。以下是示例: test_dict={'a/a':'result1',“a/a b/b c/c”:“result2”} 句子=“某物” 结果=多次替换(测试记录,句子) def多重_替换(dict,文本): regex=re.compile((%s)“%”“|”。join(map(re.escape,dict.keys())) 返回regex.sub(lambda mo:dict[mo.s

我有一个包含键、值对的python字典,我想用相应的值替换字典中键的字符串中的一些单词

我尝试了一些在线代码。以下是示例:

test_dict={'a/a':'result1',“a/a b/b c/c”:“result2”}
句子=“某物”
结果=多次替换(测试记录,句子)
def多重_替换(dict,文本):
regex=re.compile((%s)“%”“|”。join(map(re.escape,dict.keys()))
返回regex.sub(lambda mo:dict[mo.string[mo.start():mo.end()],text)
我希望结果是
something


实际输出是
something

您的代码替换了字符串中找到的所有
a/a
,这意味着不再需要替换a/a b/b c/c


如果您用/
包围每个键,搜索该键,并将其替换,然后放回
,则可以避免此问题。

问题是
将被替换为
'a/a':'result1'
,从而导致
在更换a/a b/b c/c之前

您应该从更具体的到不太具体的开始进行替换。实现这一点的一种方法是使用
OrderedDict
并从另一个方向定义规则:

import re
from collections import OrderedDict

test_dict = OrderedDict([("a/a b/b c/c", "result2"), ('a/a', 'result1'),])

sentence = "<<a/a>> something <<a/a b/b c/c>> something"

def multiple_replace(dict, text):
    regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
    return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)

result = multiple_replace(test_dict, sentence)
重新导入
从集合导入订单
test_dict=OrderedDict([(“a/a b/b c/c”,“result2”),(“a/a”,“result1”),]))
句子=“某物”
def多重_替换(dict,文本):
regex=re.compile((%s)“%”“|”。join(map(re.escape,dict.keys()))
返回regex.sub(lambda mo:dict[mo.string[mo.start():mo.end()],text)
结果=多次替换(测试记录,句子)

输出是:
something/something
您的问题是,您的第一个重新定距的键
'a/a'
是另一个键
'a/a b/b c/c'的一部分。较长的键不再替换,因为
'a/a'
的规则更改了文本,因此它将不再找到
'a/a b/b c/c'

如果通过减少长度对键进行排序,可以避免这种情况,因此首先替换较长的键:

import re

def multiple_replace(d, text):
    # sort keys by -len so longer ones come first (you could use reverse=True as well)
    regex = re.compile("(%s)" % "|".join(map(re.escape, 
                                             sorted(d.keys(),key=lambda x:-len(x)))))
    return regex.sub(lambda mo: d[mo.string[mo.start():mo.end()]], text)

test_dict = {'a/a': 'result1', "a/a b/b c/c": "result2"}

sentence = "<<a/a>> something <<a/a b/b c/c>> something"

result = multiple_replace(test_dict, sentence)
print(result)
重新导入
def多重_替换(d,文本):
#按-len对键进行排序,使较长的键优先(您也可以使用reverse=True)
regex=re.compile((%s)“%”“|”,
已排序(d.keys(),key=lambda x:-len(x‘‘‘‘)’)
返回regex.sub(lambda mo:d[mo.string[mo.start():mo.end()],文本)
test_dict={'a/a':'result1',“a/a b/b c/c”:“result2”}
句子=“某物”
结果=多次替换(测试记录,句子)
打印(结果)
输出:

<<result1>> something <<result2>> something
某物
如果被替换的值包含较短键的一部分,则仍然会有问题,它将再次被部分替换