Python正则表达式替换引号中的文本,除了引号本身

时间:2014-03-23 03:37:35

标签: python regex

所以我有一个测试字符串,例如

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

我想使用正则表达式来删除双重语音标记之间的文本,而不是语音标记本身。所以它会返回

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

我正在使用以下代码

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

但这也消除了双重语音标记。 我应该使用什么模式来保留语音标记,但删除其中的文本。

3 个答案:

答案 0 :(得分:9)

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

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

BTW,.*尽可能匹配(贪婪)。要匹配非贪婪时尚,请使用.*?[^"]*

>>> 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. ""

答案 1 :(得分:5)

你也可以使用lookarounds:

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

Regular expression visualization

Debuggex Demo

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

两个注释:

  • .*会捕获字符串中 last 双引号的所有内容,而不是 next 。这就是为什么我把它[^"]+
  • 重要的是,当两个双引号子字符串在整个字符串中时,这将不起作用,除非增加下一个搜索开始的索引。所以,例如,

    我张开嘴,“早上好!”我高兴地说。 “每个人怎么样?”

为了捕获I said cheerfully.,必须在“早上好!”之后将索引递增一。

答案 2 :(得分:2)

您可能想要使用“环视”表达式:

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

这表示“匹配任何前面带有引号并后跟引号的内容”。

这种方法的优点是你可以在外观中有不同的东西 - 例如,你可以匹配(?<"|')以匹配单引号或双引号,并留下引号标记。如果你硬连接你“更换并放回”的东西,你就不能这样做。

在我写的形式中,这将是一个“贪婪”的匹配 - 也就是说,它将匹配尽可能大的表达式。如果你有多对引号,你可能想要使用“非贪婪量词”.*?,它表示“一旦你得到匹配就停止”(即停在下一个双引号)。你也可以明确地匹配“只有不是双引号的东西”,即

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

请注意,您仍然需要“结束引用”,因此您不会最终匹配从单引号到字符串末尾的所有内容。