如何将模式与可选的周围引号相匹配?

时间:2010-08-25 18:19:11

标签: regex quotations repeat surround

如何编写与可以包含引号的模式匹配的正则表达式,但如果匹配,则必须在开头和结尾都有匹配的引号?

"?(pattern)"?

不会起作用,因为它会允许以引号开头但不以一个结尾的模式。

"(pattern)"|(pattern)

会起作用,但是重复。有没有更好的方法来做到这一点而不重复模式?

4 个答案:

答案 0 :(得分:18)

您可以使用backreferencesconditionals无需重复即可获得解决方案:

/^(")?(pattern)(?(1)\1|)$/

匹配

  • 图案
  • “模式”

不匹配:

  • “图案
  • 图案“

然而,这种模式有些复杂。它首先查找可选引用,如果找到,则将其置于反向引用1中。然后它搜索您的模式。然后它使用条件语法来说“如果再次找到反向引用1,则匹配它,否则不匹配”。整个模式是anchored(这意味着它需要单独出现在一行上),以便不会捕获不匹配的引号(否则pattern中的pattern"将匹配)。

请注意,对条件的支持因引擎而异,更加冗长但重复的表达式将得到更广泛的支持(并且可能更容易理解)。


更新:此正则表达式的一个更简单的版本是/^(")?(pattern)\1$/,它不需要条件。当我最初测试时,我使用的测试仪给了我一个假阴性,这导致我打折它(哎呀!)。

我将保留解决方案的条件性后代和兴趣,但这是一个更简单的版本,更有可能在更广泛的引擎中工作(反向引用是这里使用的唯一可能不受支持的功能)

答案 1 :(得分:2)

这也非常简单:(".+"|.+)。确保第一个匹配项带有引号,第二个匹配项不带引号。

答案 2 :(得分:0)

根据您使用的语言,您应该能够使用反向引用。这样的话,说:

(["'])(pattern)\1|^(pattern)$

这样,你要求没有引号,或者两端都使用了SAME引用。

答案 3 :(得分:0)

这应该适用于递归正则表达式(需要更长时间才能正确)。与此同时:在 Perl 中,您可以构建自我修改正则表达式。我会把它留作学术榜样; - )

my @stuff = ( '"pattern"', 'pattern', 'pattern"', '"pattern'  );

foreach (@stuff) {
   print "$_ OK\n" if /^
                        (")?
                        \w+
                        (??{defined $1 ? '"' : ''})
                       $
                      /x
}

结果:

"pattern" OK
pattern OK
相关问题