【问题标题】:Python: Why is re.sub not replacing dict key with dict value when there is ',' in dict keyPython:当字典键中有','时,为什么re.sub没有用字典值替换字典键
【发布时间】:2014-01-13 03:53:21
【问题描述】:

这里有点像 python/编程新手。先上代码:

import re
patt_list = ['However,', 'phenomenal', 'brag']
dictionary = {'phenomenal': 'phenomenal|extraordinary|remarkable|incredible', 'However,': 'However,|Nevertheless,|Nonetheless,', 'brag': 'brag|boast'}

def replacer_factory1(dictionary):
    def replacing(match):
        if len(dictionary) > 0:
            word = match.group()
            exchange = dictionary.get(word, word)
            spintax = '{' + exchange + '}'
            create_place_holder = spintax.replace(' ', '#!#')
            return create_place_holder
        else:
            return ""
    return replacing

def replacing1(text):
    regex_patt_list = r'\b(?:' + '|'.join(patt_list) + r')\b'
    replacer = replacer_factory1(dictionary)
    return re.sub(regex_patt_list, replacer, text)

with open('test_sent.txt', 'r+') as sent:
    read_sent = sent.read()
    sent.seek(0)
    sent.write(replacing1(read_sent))

因此,我在此处创建的代码在文本文件 test_sent.txt 中搜索我在名为 patt_list 的列表中的单词。如果单词在文本文件中,则使用 re.sub 将名为 dictionary 的字典中的键替换为该字典中的相应值,然后将这些更改写回文本文件。 (这段代码实际上是一个更大的脚本的一部分,其中字典的键是从patt_list 创建的,以防你想知道为什么这里需要patt_list)。

但是,我在这段代码中遇到的问题是字典键 However, 没有被其对应的值 However,|Nevertheless,|Nonetheless, 替换 - 而其余的键:值替换工作正常,并且被写入文本文件。

我相信可能是However, 中的逗号导致了这个问题,因为我尝试了另一个键:在键末尾带有逗号的值,但这也不起作用。

谁能告诉我为什么会这样?

运行代码前'test_sent.txt'的内容:

Quite phenomenal. However, nothing to brag about?

运行代码后'test_sent.txt'的内容:

Quite {phenomenal|extraordinary|remarkable|incredible}. However, nothing to {brag|boast} about?

我真正希望输出的样子:

Quite {phenomenal|extraordinary|remarkable|incredible}. {However,|Nevertheless,|Nonetheless,} nothing to {brag|boast} about bragg's vinegar?

我不想要的(bragg's 上的部分匹配):

Quite {phenomenal|extraordinary|remarkable|incredible}. {However,|Nevertheless,|Nonetheless,} nothing to {brag|boast} about {brag|boast}g's vinegar?

编辑:响应下面“WKPLUS”的有用答案,从regex_patt_list 的末尾删除\b 在这里工作,但不是为了更大的用途,我有这个代码。字典实际上要大得多,所以当\b 被删除时,我在文本中得到部分匹配,这是我不想要的。我更新了test_sent.txt,在末尾添加了bragg's vinegar,以说明删除\b时的部分匹配问题。

【问题讨论】:

  • 与问题无关,但您可以使用functools.partial,而不是使用replacer_factory1。
  • 尝试删除正则表达式周围的边界
  • 请注意我的 OP 中的 EDIT,删除边界无效。

标签: python regex dictionary


【解决方案1】:

删除 regex_patt_list 中的第二个“\b”将解决您的问题。

def replacer_factory1(dictionary):
    def replacing(match):
        if len(dictionary) > 0:
            word = match.group()[:-1]
            exchange = dictionary.get(word, word)
            spintax = '{' + exchange + '}'
            create_place_holder = spintax.replace(' ', '#!#')
            return create_place_holder + match.group()[-1]
        else:
            return ""
    return replacing

def replacing1(text):
    regex_patt_list = r'\b(?:' + '|'.join(patt_list) + r')\W'
    replacer = replacer_factory1(dictionary)
    return re.sub(regex_patt_list, replacer, text)

为您的问题提供一个棘手的解决方案。

【讨论】:

  • 没错。逗号不是出现在单词边界内的字符。换句话说,以下不包含两个单词边界内的单个单词:\b然而,\b。第二个 \b 将指代一个新单词的开头。
  • 这在我放在这里的代码实例中确实有效。但是,我的实际字典要大得多,所以当我尝试使用完整文章的完整脚本时,我遇到了一些部分单词匹配问题,我不会这样做。很抱歉造成这种混乱,但现在我们明白了这个问题。我只需要重做正则表达式以在最后说明/b,再加上一个包含逗号的选项。
  • @Darren 更新答案。
  • 工作如梦,谢谢。我在一个大文本文件上对其进行了测试,一切看起来都很好。
【解决方案2】:

我想我看到了这个问题。逗号不被视为“单词字符”。因此,在字符串 'However' 中,逗号实际上将被视为结束词边界,而不是其后的空格。由于这种混淆,您通过使用单词边界快捷方式“\b”定义的正则表达式模式与该单词不匹配。

如果您将最后的 \b 替换为 \W(对于非单词字符),它会按照您想要的方式工作吗?

【讨论】:

    猜你喜欢
    • 2018-09-11
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 2013-08-31
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 2022-07-05
    相关资源
    最近更新 更多