所以我有一个测试字符串,例如
content = 'I opened my mouth, "Good morning!" I said cheerfully'
我想使用正则表达式来删除双重语音标记之间的文本,而不是语音标记本身。所以它会返回
'I opened my mouth, "" I said cheerfully'
我正在使用以下代码
content = re.sub(r'".*"'," ",content)
但这也消除了双重语音标记。 我应该使用什么模式来保留语音标记,但删除其中的文本。
答案 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:
(?<=")([^"]+)(?=")
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)
请注意,您仍然需要“结束引用”,因此您不会最终匹配从单引号到字符串末尾的所有内容。