正则表达式匹配一个或两个引号,但不是连续三个

Posted

技术标签:

【中文标题】正则表达式匹配一个或两个引号,但不是连续三个【英文标题】:Regex to match one or two quotes but not three in a row 【发布时间】:2014-01-05 17:27:41 【问题描述】:

这辈子我都想不通。

我需要搜索以下文本,仅匹配粗体引号:

不匹配:"""这是一个 python 文档字符串"""

匹配:" 这是一个常规字符串 "

匹配:"" ← 那是一个空字符串

如何使用正则表达式做到这一点?

这是我尝试过的:

不起作用

(?!"")"(?<!"")

关闭,但不匹配双引号。

不起作用

"(?<!""")|(?!"")"(?<!"")|(?!""")"

我天真地以为我可以添加我不想要的替代品,但逻辑最终颠倒了。这个匹配所有内容,因为所有引号都至少匹配一个备用引号。

(请注意:我没有运行代码,所以使用 __doc__ 的解决方案无济于事,我只是想在我的代码编辑器中查找和替换。)

【问题讨论】:

【参考方案1】:

你可以使用/(?&lt;!")"1,2(?!")/

DEMO

尸检

(?&lt;!") 对文字 " 的负面回溯。匹配不能在前面有这个字符 "1,2 文字 " 匹配一次或两次 (?!") 对文字 " 的负前瞻。匹配不能在之后有这个字符

您的第一次尝试可能失败了,因为(?!") 是一个否定的look-ahead,而(?&lt;!") 是一个否定的look-behind。在比赛前进行前瞻或在比赛后进行后瞻是没有意义的。

【讨论】:

太好了,谢谢!实际上,有时在匹配之前进行前瞻是有意义的,以排除(或包含)可能的匹配。就我而言,我想看看是否可以利用它来查看完整的集合,但它没有增加任何价值。 我刚刚意识到我一次只需要匹配一个单引号字符。请查看my answer...你帮助我到达那里。我没有改变原来的问题,因为你回答得很好(而且我不想问一个如此相似的新问题)。 @NickC 不用担心。让我们希望有一天其他人可以使用这个答案。 :)【参考方案2】:

我意识到我最初的问题描述实际上有点错误。也就是说,我实际上需要只匹配一个单个引号字符,除非它是一组3个引号字符的一部分。

不同之处在于这对于编辑来说是可取的,以便我可以找到并替换为'。如果我匹配 "one or two quotes" 那么我不能自动替换为单个字符。

我想出了对h20000000's answer 的修改以满足这种情况:

(?<!"")(?<=(?!""").)"(?!"")

在demo 中,您可以看到"" 是单独匹配的,而不是作为一个组匹配的。

这与其他答案非常相似,除了:

它只匹配一个"

这让我们可以匹配我们想要的所有内容,除了它仍然匹配 """ 的中间引号

最后,添加(?&lt;=(?!""").) 专门排除这种情况,通过说“回顾一个字符,如果接下来的三个字符是""",则匹配失败):


我决定不更改问题,因为我不想劫持答案,但我认为这可能是一个有用的补充。

【讨论】:

以上是关于正则表达式匹配一个或两个引号,但不是连续三个的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式逐行:如何匹配三引号而不是双引号

正则表达式必知必会

正则表达式用引号和冒号分割

正则表达式 (C#):匹配 > < 或(非法 XML 字符)但仅当包含在引号内时

正则表达式:\B 匹配不是单词开头或结束的位置

java 正则表达式 包含字母数字特殊字符