1

我有一个键值对的python字典,我想用它们对应的值替换字符串中的一些词,这些词是字典中的键。

我尝试了一些在线找到的代码。这是示例:

    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)

    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)

我预计结果是<<result1>> something <<result2>> something

实际输出为<<result1>> something <<result1 b/b c/c>> something

4

3 回答 3

1

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

<<如果你用and包围每个键>>,搜索那个,然后把它放回<<& >>,你就可以避免这个问题。

于 2019-08-14T12:24:39.997 回答
1

问题是在替换发生之前<<a/a b/b c/c>>将被替换。'a/a': 'result1'"<<result1 b/b c/c>>"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)

输出是:<<result1>> something <<result2>> something

于 2019-08-14T12:25:26.857 回答
0

您的问题是您的第一个 relpaced 键'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)

输出:

<<result1>> something <<result2>> something

如果被替换的值包含较短键的一部分,您仍然会遇到问题,它将再次被部分替换。

于 2019-08-14T12:28:16.830 回答