首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用正则表达式执行多个替换?

如何使用正则表达式执行多个替换?
EN

Stack Overflow用户
提问于 2013-03-02 21:43:48
回答 6查看 85.6K关注 0票数 56

我可以使用下面的代码创建一个新文件,使用正则表达式将a替换为aa

代码语言:javascript
复制
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-->aab--> bbc--> cc

所以我必须为我想要更改的所有字母写一行,或者有一种更简单的方法。也许是为了创建一本翻译的“字典”。我应该把这些字母放入一个数组中吗?如果我这样做了,我不知道该怎么打电话给他们。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-03-02 21:53:32

@nhahtdh提出的答案是有效的,但我认为比起规范的示例,它使用的代码不像他的regex操作那么不透明,并利用了python的内置数据结构和匿名函数功能。

在这种情况下,翻译词典是有意义的。事实上,Python Cookbook就是这样做的,如本例所示(复制自ActiveState http://code.activestate.com/recipes/81330-single-pass-multiple-replace/ )

代码语言:javascript
复制
import re 

def multiple_replace(dict, text):
  # Create a regular expression  from the dictionary keys
  regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))

  # For each match, look-up corresponding value in dictionary
  return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text) 

if __name__ == "__main__": 

  text = "Larry Wall is the creator of Perl"

  dict = {
    "Larry Wall" : "Guido van Rossum",
    "creator" : "Benevolent Dictator for Life",
    "Perl" : "Python",
  } 

  print multiple_replace(dict, text)

因此,在您的例子中,您可以创建一个dict trans = {"a": "aa", "b": "bb"},然后将其与您希望翻译的文本一起传递到multiple_replace中。基本上,该函数所做的就是创建一个包含所有要翻译的正则表达式的巨大正则表达式,然后当找到一个正则表达式时,将一个lambda函数传递给regex.sub以执行翻译字典查找。

您可以在读取文件时使用此函数,例如:

代码语言:javascript
复制
with open("notes.txt") as text:
    new_text = multiple_replace(replacements, text.read())
with open("notes2.txt", "w") as result:
    result.write(new_text)

我实际上已经在生产中使用了这种方法,在一次web抓取任务中,我需要将一年中的几个月从捷克语翻译成英语。

正如@nhahtdh所指出的,这种方法的一个缺点是它不是无前缀的:作为其他字典键的前缀的字典键将导致方法崩溃。

票数 70
EN

Stack Overflow用户

发布于 2019-08-27 23:58:21

您可以使用pandas库和replace函数。我用五个替换来表示一个例子:

代码语言:javascript
复制
df = pd.DataFrame({'text': ['Billy is going to visit Rome in November', 'I was born in 10/10/2010', 'I will be there at 20:00']})

to_replace=['Billy','Rome','January|February|March|April|May|June|July|August|September|October|November|December', '\d{2}:\d{2}', '\d{2}/\d{2}/\d{4}']
replace_with=['name','city','month','time', 'date']

print(df.text.replace(to_replace, replace_with, regex=True))

修改后的文本为:

代码语言:javascript
复制
0    name is going to visit city in month
1                      I was born in date
2                 I will be there at time

您可以找到示例here

票数 5
EN

Stack Overflow用户

发布于 2020-05-22 18:02:22

如果您的模式本身是正则表达式,则其他解决方案都不起作用。

为此,您需要:

代码语言:javascript
复制
def multi_sub(pairs, s):
    def repl_func(m):
        # only one group will be present, use the corresponding match
        return next(
            repl
            for (patt, repl), group in zip(pairs, m.groups())
            if group is not None
        )
    pattern = '|'.join("({})".format(patt) for patt, _ in pairs)
    return re.sub(pattern, repl_func, s)

它可以用作:

代码语言:javascript
复制
>>> multi_sub([
...     ('a+b', 'Ab'),
...     ('b', 'B'),
...     ('a+', 'A.'),
... ], "aabbaa")  # matches as (aab)(b)(aa)
'AbBA.'

请注意,此解决方案不允许您将捕获组放入正则表达式中,也不允许将它们用于替换。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15175142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档