【问题标题】:Find and Replace Operation Using Regex with Inner Function Not Working使用内部函数不起作用的正则表达式查找和替换操作
【发布时间】:2018-07-31 17:43:57
【问题描述】:

我是 Stack Overflow 上的新手,希望有人可以帮助我编写以下代码。

我正在尝试改编来自 Ascher、Ravenscroft 和 Martelli Python Cookbook 的一段代码。我想使用字典键:值对(所有文本都是 utf-8)将 Text 中包含“long-s”的所有单词替换为用现代小写 s 拼写的等效单词。我能够毫无问题地从现有的制表符分隔文件构建字典(我在代码中使用了一个简单的示例字典以便于编辑),但是我想一次完成所有更改以提高速度和效率.我已经删除了代码的mapescape 部分,因为我认为'long-s' 不需要转义(不过我可能是错的!)。第一部分工作正常,但内部函数one_xlat 似乎没有做任何事情。最后它不会返回/打印Text,也没有错误消息。我已经在命令行和 IDLE 中运行了代码,结果相同。我已经在使用和不使用mapescape 的情况下运行了代码,并且为了确定,我已经重命名了变量,但我不能让它工作。有人可以帮忙吗?抱歉,如果我遗漏了一些明显的东西,并提前非常感谢您。

来自 Ascher、Ravenscroft 和 Martelli 的原始代码:

import re
def multiple_replace(text, adict):
    rx = re.compile('|'.join(map(re.escape, adict)))
    def one_xlat(match):
        return adict[match.group(0)]
    return rx.sub(one_xlat, text)

改编版:

import re

adictCR = {"handſome":"handsome","ſeated":"seated","veſſels":"vessels","ſea-side":"sea-side","ſand":"sand","waſhed":"washed", "oſ":"of", "proſpect":"prospect"}
text = "The caſtle, which is very extenſive, contains a ſtrong building, formerly uſed by the late emperor as his principal treaſury, and a noble terrace, which commands an extensive proſpect oſ the town of Sallee, the ocean, and all the neighbouring country."

def word_replace(text, adictCR):
    regex_dict = re.compile('|'.join(adictCR))
    print(regex_dict)
    def one_xlat(match):
        return adictCR[match.group(0)]
    return regex_dict.sub(one_xlat, text)
    print(text)

word_replace(text, adictCR)

【问题讨论】:

  • 在我看来,您已将变量名从 rx 更改为 regex_dict,但之后仍继续使用 rx。
  • 使用 dict 本身进行替换也可能更容易。正则表达式在这里没有优势。
  • MandyShaw - 非常感谢您指出错误。我已更正此问题,但问题仍然存在。
  • 还有 dawg - 感谢您的回复。我希望使用正则表达式,因为我理解它将使替换操作一次发生,而不是使用replace,这会导致创建文本的多个副本。我有这个正确的吗?抱歉,如果我不这样做!最终,代码将用于处理具有非常大字典的数千页,因此我试图将效率放在首位。希望这是有道理的!再次感谢。
  • str.replace 对替换进行可选计数。如果这是您的目标,那将大大加快速度。做类似1)逐字循环文本; 2)检查字典中的单词; 3)如果在字典中找到替换单词; 4) 利润!

标签: python regex python-3.x dictionary


【解决方案1】:

我会这样重写你的代码:

# -*- coding: utf-8 -*-
import re

adictCR = {"handſome":"handsome","ſeated":"seated","veſſels":"vessels","ſea-side":"sea-side","ſand":"sand","waſhed":"washed", "oſ":"of", "proſpect":"prospect"}
text = "The caſtle, which is very extenſive, contains a ſtrong building, formerly uſed by the late emperor as his principal treaſury, and a noble terrace, which commands an extensive proſpect oſ the town of Sallee, the ocean, and all the neighbouring country."

new_s=[]        
for g in (m.group(0) for m in re.finditer(r'\w+|\W+', text)):
    if g in adictCR:
        g=adictCR[g]
    new_s.append(g)

然后您可以使用''.join(new_s) 获取新字符串。

注意:'\w+|\W+' 模式仅适用于具有非 ascii 文本的 Python 最新版本(3.1+)。您也可以将split(r'(\W)', str) 作为替代,但我认为这不适用于带有 utf-8 的 Python 2。

【讨论】:

  • Dawg - 非常感谢您的帮助。我正在使用 Python 3.7,所以你的建议很有效。感谢您抽出宝贵时间提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-09
  • 2020-12-22
  • 2017-05-13
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多