一个人如何编写一个匹配可以包含报价的模式的正则表达式,但是如果这样做,必须在开始和结束时具有匹配的引号?

"?(pattern)"?

不会工作,因为它将允许以报价开头但不会以一个开始的方式。

"(pattern)"|(pattern)

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

有帮助吗?

解决方案

您可以通过使用而无需重复解决方案 反向有条件:

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

火柴:

  • 图案
  • “图案”

不匹配:

  • “图案
  • 图案”

但是,这种模式有些复杂。它首先要寻找可选的报价,并在发现时将其放入反向注册1中。然后它搜索您的模式。然后,它使用条件语法说“如果再次找到反向1,则匹配,否则什么也不匹配”。整个模式是 锚定 (这意味着它需要独自出现在一条行上),因此不会捕获无与伦比的报价(否则 patternpattern" 会匹配)。

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


更新: 此正则更简单的版本将是 /^(")?(pattern)\1$/, ,这不需要条件。当我最初对此进行测试时,我使用的测试仪给了我一个虚假的负面,这使我打折了(糟糕!)。

我将把解决方案留给有条件的后代和兴趣,但这是一个更简单的版本,更有可能在更广泛的发动机中使用(反向报道是这里使用的唯一功能,可能不支持)。

其他提示

根据您使用的语言,您应该能够使用反向报道。这样的事情说:

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

这样,您要求没有报价,或者两端都使用相同的报价。

这应该与递归的正则表达式(需要更长的时间才能正确)。同时:在 珀尔, ,您可以构建 自我修改的正则是. 。我将其作为学术示例;-)

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

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

结果:

"pattern" OK
pattern OK
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top