【问题标题】:Error: nothing to repeat at position错误:没有重复的位置
【发布时间】:2018-02-12 16:21:46
【问题描述】:

我有一个文本文件,其中包含俚语列表及其在真实英语中的替代词。我使用“:”作为分割点将此文本文件转换为字典,并且在转换后打印字典时一切似乎都很好。

但是,来自此行的错误:slangs_re = re.compile('|'.join(slang_dict.keys())) 表示 nothing to repeat at position 112207

在尝试调试时,我发现错误以某种方式与字典相关联。这是因为当我运行下面的代码时,我没有得到正确的输出,但我也没有得到错误。此代码的预期输出是“fitness”,但实际输出是“fitess”。

import re

test = "fitess"

slang_dict = {"fitess":"fitness", "damm":"damn"}

slangs_re = re.compile('|'.join(slang_dict.keys()))

def correct_slang(s, slang_dict=slang_dict):
    def replace(match):
        return slang_dict[match.group(0)]

    return slangs_re.sub(replace, s)

test = correct_slang(test)
print(test)

这是包含字典的代码(抱歉,文本文件太大,无法包含。有一个示例here)。预期的输出是“fitness”,但实际的输出是错误的:

import re

test = "fitess"

file = open("slang_conversion.txt","r")

slang_dict = {}

for line in file:
    x = line.split(":")
    a = x[0]
    b = x[1]
    c = len(b) - 1

    b = b[0:c]

    slang_dict[a] = b

slangs_re = re.compile('|'.join(slang_dict.keys())) # <-- error

def correct_slang(s, slang_dict=slang_dict):
    def replace(match):
        return slang_dict[match.group(0)]

    return slangs_re.sub(replace, s)

test = correct_slang(test)

print(test)

在阅读其他 SO 线程后,我知道在某些情况下这是一个错误,但在这种情况下似乎不是。

谢谢

【问题讨论】:

  • 如果slang_dict.keys() 包含正则表达式元字符(*+ 等),则需要对其进行转义。
  • 很可能,您可以使用r"(?&lt;!\w){}(?!\w)".format('|'.join([re.escape(x) for x in slang_dict.keys()])) 修复它。或者,如果所有单词都由字母、数字和_ 组成,您甚至可以使用\w+ 模式并在尝试获取值之前检查该键是否存在于字典中。
  • 此外,contractions_re 应替换为 slangs_re。见ideone.com/VVR3ke

标签: python regex debugging dictionary


【解决方案1】:

我建议更换

slangs_re = re.compile('|'.join(slang_dict.keys()))

slangs_re = re.compile(r"(?<!\w)(?:{})(?!\w)".format('|'.join([re.escape(x) for x in slang_dict])))

并确保传递按长度降序排序的键。

from collections import OrderedDict
import re

test = "fitess no kome*"

slang_dict = {"Aha aha":"no", "fitess":"fitness", "damm":"damn", "kome*":"come", "ow wow":"rrf"}
slang_dict = OrderedDict(sorted(slang_dict.iteritems(), key=lambda x: len(x[0]), reverse=True))

slangs_re = re.compile(r"(?<!\w)(?:{})(?!\w)".format('|'.join([re.escape(x) for x in slang_dict])))
def correct_slang(s, slang_dict=slang_dict):
    def replace(match):
        return slang_dict[match.group(0)]

    return slangs_re.sub(replace, s)

test = correct_slang(test)
print(test)

Python demo

这会将术语作为整个单词进行检查,并将转义每个搜索短语中的特殊字符,以便在将它们传递给正则表达式引擎时不会出现问题。

如果您对整个单词匹配不感兴趣,请删除 (?&lt;!\w)(检查前导词边界)和 (?!\w)(检查尾随词边界)。

【讨论】:

  • 谢谢!不过,这会导致奇怪的错误。当我输入 luv 3 iphone awsm display awesome, soo happy 我希望输出是 love 3 phone awesome display awesome, soo happy。然而,这是输出:love 3 phone awesome displaywhy awesomeohame, isohoh hathappy。我查了字典中的问题,但没有。这可能是什么原因?为什么awesome变成awesomeohame?
  • @MythicCocoa 结果模式是什么?可以通过pastebin.com分享吗?
  • 你用过(?&lt;!\w){}(?!\w)吗?看起来好像你省略了整个单词检查。
  • 是的,我做到了。我会在pastebin上发布,请稍等。
  • 我不是要代码,而是要模式。在创建模式之前尝试添加slang_dict = OrderedDict(sorted(slang_dict.iteritems(), key=lambda x: len(x[0]), reverse=True))。添加from collections import OrderedDict
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-17
相关资源
最近更新 更多