如何将图案与可选的周围报价匹配?
-
01-10-2019 - |
题
一个人如何编写一个匹配可以包含报价的模式的正则表达式,但是如果这样做,必须在开始和结束时具有匹配的引号?
"?(pattern)"?
不会工作,因为它将允许以报价开头但不会以一个开始的方式。
"(pattern)"|(pattern)
会起作用,但是重复的。有没有更好的方法在不重复模式的情况下做到这一点?
解决方案
/^(")?(pattern)(?(1)\1|)$/
火柴:
- 图案
- “图案”
不匹配:
- “图案
- 图案”
但是,这种模式有些复杂。它首先要寻找可选的报价,并在发现时将其放入反向注册1中。然后它搜索您的模式。然后,它使用条件语法说“如果再次找到反向1,则匹配,否则什么也不匹配”。整个模式是 锚定 (这意味着它需要独自出现在一条行上),因此不会捕获无与伦比的报价(否则 pattern
在 pattern"
会匹配)。
请注意,对条件的支持因引擎而异,并且更详细,但重复表达式将得到更广泛的支持(并且可能更容易理解)。
更新: 此正则更简单的版本将是 /^(")?(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
不隶属于 StackOverflow