Python正则表达式替换引号内的文本但不包括引号

4 投票
3 回答
5765 浏览
提问于 2025-04-17 23:29

我有一个测试字符串,比如说

content = 'I opened my mouth, "Good morning!" I said cheerfully'

我想用正则表达式来去掉双引号里面的文字,但保留双引号本身。所以最后的结果应该是

'I opened my mouth, "" I said cheerfully'

我正在使用以下代码

content = re.sub(r'".*"'," ",content)

但是这段代码也把双引号去掉了。那我应该用什么样的模式,才能去掉引号里面的文字,但保留引号呢?

相关问题:

3 个回答

2

你可能想用“前后查找”表达式:

>>> content = 'I opened my mouth, "Good morning!" I said cheerfully'
>>> content = re.sub(r'(?<=").*(?=")', '', content)

这段意思是“匹配任何前面有引号,后面也有引号的内容”。

这种方法的好处是,你可以在前后查找中使用不同的东西。例如,你可以用 (?<"|') 来匹配单引号或双引号,而不去改变那个引号本身。如果你直接把要“替换并放回”的内容写死,就做不到这一点。

我写的这个形式会是一个“贪婪”的匹配,也就是说,它会尽量匹配尽可能大的内容。如果你有多个引号对,你可能想用“非贪婪量词” .*?,它的意思是“只要找到匹配就停下来”(也就是说,停在下一个双引号那里)。你也可以明确匹配“只匹配不是双引号的内容”,也就是:

re.sub(r'(?<=")[^"]*(?=")', '', content) 

注意,你仍然需要“结束引号”,这样你就不会从一个引号开始匹配到字符串的末尾。

7

你还可以使用“前后查找”的方法:

(?<=")([^"]+)(?=")

正则表达式可视化

Debuggex 演示

content = re.sub(r'(?<=")([^"]+)(?=")', '', content)

有两个注意事项:

  • .* 会抓取你字符串中到最后一个双引号之间的所有内容,而不是下一个双引号。这就是为什么我把它改成了 [^"]+
  • 重要的是,当整体字符串中有两个双引号的子字符串时,这个方法是行不通的,除非你在下次搜索开始时增加索引位置。所以,比如说,假设有这样一句:

    我张嘴说:“早上好!”我愉快地说。“大家怎么样?”

为了抓取 我愉快地说。,你必须在找到“早上好!”后,把索引位置增加一。

12

使用 '""' 作为替换字符串:

>>> content = 'I opened my mouth, "Good morning!" I said cheerfully'
>>> content = re.sub(r'".*"', '""', content)
>>> print(content)
I opened my mouth, "" I said cheerfully

顺便说一下,.* 会尽量匹配尽可能多的内容(贪婪匹配)。如果你想要非贪婪匹配,可以使用 .*? 或者 [^"]*

>>> content =  'I opened my mouth, "Good morning!" I said cheerfully. "How is everyone?"'
>>> content = re.sub(r'".*?"', '""', content)
>>> print(content)
I opened my mouth, "" I said cheerfully. ""

撰写回答