我可以使用下面的代码创建一个新文件,使用正则表达式将a
替换为aa
。
import re
with open("notes.txt") as text:
new_text = re.sub("a", "aa", text.read())
with open("notes2.txt", "w") as result:
result.write(new_text)
我想知道我是否必须多次使用new_text = re.sub("a", "aa", text.read())
这一行,但要用字符串替换我想更改的其他字母,以便更改文本中的多个字母?
也就是说,a
--〉aa
,b
--〉bb
和c
--〉cc
。
所以我必须为所有我想修改的字母写一行,或者有一个更简单的方法。也许创建一个翻译的“字典”。我应该把这些字母放入一个数组中吗?如果我这样做了,我不知道如何调用它们。
9条答案
按热度按时间pftdvrlh1#
@nhahtdh给出的答案是正确的,但是我认为这个例子没有规范的例子那么像python,规范的例子使用了比正则表达式操作更透明的代码,并且利用了python内置的数据结构和匿名函数特性。
翻译字典在这个上下文中是有意义的,事实上,Python Cookbook就是这样做的,如这个例子所示(从ActiveState http://code.activestate.com/recipes/81330-single-pass-multiple-replace/复制而来)
因此,在您的例子中,您可以创建一个dict
trans = {"a": "aa", "b": "bb"}
,然后将其与要翻译的文本沿着传递给multiple_replace
,基本上该函数所做的全部工作是创建一个包含所有要翻译的正则表达式的大型正则表达式,然后当找到一个正则表达式时,将lambda函数传递给regex.sub
以执行翻译字典查找。您可以在阅读文件时使用此函数,例如:
我实际上在生产中使用过这种精确的方法,在一个Web抓取任务中,我需要将一年中的月份从捷克语翻译成英语。
正如@nhahtdh指出的,这种方法的一个缺点是它不是无前缀的:作为其他字典键的前缀的字典键将导致该方法中断。
s71maibg2#
可以使用捕获组和反向引用:
将要加倍的字符放在
[]
之间。对于小写的a
、b
、c
:在替换字符串中,可以引用捕获组
()
匹配的任何内容,其表示法为\n
,其中n
是某个正整数(不包括0)。\1
引用第一个捕获组。还有另一种表示法\g<n>
,其中n
可以是任何非负整数(允许0);\g<0>
将引用表达式匹配的整个文本。如果要将除新行以外的所有字符加倍:
如果要将所有字符(包括新行)加倍:
chhkpiq43#
您可以使用
pandas
库和replace
函数。我给出了一个示例,其中有五个替换:修改后的文本为:
您可以找到示例here
f0brbegy4#
如果您的模式本身就是正则表达式,那么其他解决方案都不起作用。
为此,您需要:
可用作:
注意,这个解决方案不允许您将捕获组放在正则表达式中,或者在替换中使用它们。
bnl4lu3b5#
使用how to make a 'stringy' class中的技巧,我们可以让一个对象等同于一个字符串,但需要一个额外的
sub
方法:这允许使用builder模式,它看起来更漂亮,但是只对预定数量的替换有效。如果你在循环中使用它,就没有必要再创建额外的类了。
n3h0vuf26#
我发现我不得不修改Emmett J.Butler的代码,将lambda函数改为使用myDict.get(mo.group(1),mo.group(1))。使用myDict.get()还提供了在没有找到键时使用默认值的好处。
0sgqnhkj7#
如果你处理文件,我有一个简单的python代码关于这个问题。更多信息here。
sg24os4d8#
基于Eric's great answer,我提出了一个更通用的解决方案,它能够处理捕获组和反向引用:
给出:
对于更有效的解决方案,可以创建简单的 Package 器来预先计算
groups_no
和full_pattern
,例如:按如下方式使用它:
n3h0vuf29#
我不知道为什么大多数的解决方案都试图组合一个正则表达式模式而不是多次替换。这个答案只是为了完整性。
也就是说,这种方法的输出与组合regex方法的输出不同。也就是说,重复的替换可能会使文本随时间演变。但是,以下函数返回的输出与调用unix sed的输出相同:
用法:
使用相同的输入和规则,其他解决方案将输出"bc"。根据您的使用情况,您可能希望或不希望连续替换字符串。在我的情况下,我希望重新构建sed行为。另外,请注意规则的顺序很重要。如果您颠倒规则顺序,此示例也将返回"bc"。
这种解决方案比将模式组合成一个正则表达式要快(快100倍),所以,如果用例允许的话,应该首选重复替换方法。
当然,您可以编译正则表达式模式: