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

10

我真的想不出来这个问题的答案。

我需要搜索以下文本,只匹配加粗引号中的内容:

不要匹配: """This is a python docstring"""

匹配:" 这是一个普通字符串 "

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

我该如何用正则表达式实现这一点?

这是我尝试过的:

无法使用

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

接近了,但没有匹配双引号。

不起作用

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

我天真地认为我可以添加我不想要的备选项,但逻辑却反了过来。这个匹配所有内容,因为所有引号都至少符合其中一个备选项。

(请注意:我没有运行代码,所以使用__doc__的解决方案对我没有帮助,我只是试图在我的代码编辑器中查找和替换。)

2个回答

26

你可以使用/(?<!")"{1,2}(?!")/

演示

解剖

  • (?<!") 对于文字 " 的负向先行断言。匹配不能在其前面有此字符
  • "{1,2} 文字 " 匹配一次或两次
  • (?!") 对于文字 " 的负向预查。匹配不能在其后面有此字符

你的第一次尝试可能失败了,因为(?!") 是一个负向预查,而(?<!") 是一个负向先行断言。在你的匹配之前使用预查是没有意义的,在你的匹配之后使用先行断言也是如此。

Regular expression visualization


太好了,谢谢!实际上,在匹配之前进行预测有时是有意义的,以便排除(或包含)可能的匹配项。在我的情况下,我正在看是否可以利用它来查看完整集合,但它并没有增加任何价值。 - Nicole
我刚刚意识到我只需要一次匹配单引号字符。请查看我的答案……你帮助我到达了那里。我没有改变原来的问题,因为你已经完美地回答了它(而且我不想问一个如此相似的新问题)。 - Nicole
@NickC 不用担心。希望有人能在将来使用这个答案。 :) - h2ooooooo

2
我意识到我的原始问题描述实际上略有偏差。也就是说,我需要实际上只匹配一个单引号字符,除非它是三个引号字符组的一部分。
区别在于这对编辑很有用,这样我就可以查找和替换为'。如果我匹配"一个或两个引号",那么我就无法自动替换为单个字符。
我对h20000000的答案做了如下修改,以满足此情况:
(?<!"")(?<=(?!""").)"(?!"")

正则表达式可视化

演示中,您可以看到""被单独匹配,而不是作为一个组进行匹配。

这个方法与其他答案非常相似,但有以下几点不同:

  • 它只匹配单个"
  • 这使得我们能够匹配除"""之外的所有内容,但仍然会匹配"""中间的引号

    enter image description here

  • 最后,通过添加(?<=(?!""").),特别排除了这种情况,即“向后查找一个字符,如果下一个三个字符是""",则匹配失败”:

    enter image description here


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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接