如何编写与可以包含引号的模式匹配的正则表达式,但如果匹配,则必须在开头和结尾都有匹配的引号?
"?(pattern)"?
不会起作用,因为它会允许以引号开头但不以一个结尾的模式。
"(pattern)"|(pattern)
会起作用,但是重复。有没有更好的方法来做到这一点而不重复模式?
答案 0 :(得分:18)
您可以使用backreferences和conditionals无需重复即可获得解决方案:
/^(")?(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