Fal*_*lko 5 javascript php regex regex-group quantifiers
我刚刚在http://regexcrossword.com/上做了有趣的正则表达式填字游戏- 并且发现我不明白量化群体意味着什么,例如(.)+或(.)*
让我试试http://ole.michelsen.dk/tools/regex.html,它提供了JavaScript和PHP正则表达式引擎:
要匹配的字符串是"Trololo!" (不带引号).(如果打开"全局匹配"改变了某些东西,它会被添加为引导版本,即JS',因为它在PHP模式下没有任何改变.)
JS, (.)+ => 0: Trololo! 1: !
JS', (.)+ => 0: Trololo!
PHP, (.)+ => 0: Trololo! 0: !
JS, (.)* => 0: Trololo! 1: !
JS', (.)* => 0: Trololo!
PHP, (.)* => 0: Trololo! 1: 0: ! 1:
JS, (.){5} => 0: Trolo 1: o
JS', (.){5} => 0: Trolo
PHP, (.){5} => 0: Trolo 0: o
JS, (.){4} => 0: Trol 1: l
JS', (.){4} => 0: Trol 1: olo!
PHP, (.){4} => 0: Trol 1: olo! 0: l 1: !
Run Code Online (Sandbox Code Playgroud)
有没有任何规范性的答案,这是什么语义?
输出没有正确标记,仅此而已。
首先,应该发生什么?如果重复一个组,每个新实例都会覆盖最后一个捕获。如果根本没有使用该组,它将返回一个空字符串或类似undefinedJS 中的内容(这取决于风格)。Regular-Expressions.info上有一篇关于此事的好文章。
现在我们如何得到您的结果?让我们从 JavaScript 开始。
所有标记的示例JS(非全局示例)都符合上述描述。它们匹配 中所需的字符数量0并捕获 中的最后一个字符1。所以我们可以忽略这些。
全球的怎么了?这里的输出被错误地解释。当您在函数中使用全局标志时String.match(),您不再获得所有捕获的数组 - 而是仅获得所有匹配的数组(0每个匹配的组)。因此,在 、 的情况下+,*并且{5}只有一个匹配项,您只能得到一个结果。由于{4}目标字符串中有足够的空间容纳两个匹配项,因此生成的数组包含两个元素。要使用全局标志获取所有捕获,您需要编写一个循环并使用RegExp.exec()它(它一次为您提供一个匹配项,但其所有捕获)。
PHP 又如何呢?看起来它正在使用preg_match_all,无论如何,这是全局的,这就是为什么使用g没有效果。这+会再次给出您期望的结果。也是如此{5}。
另外两个怎么了?在这里,输出被以错误的方式解释。默认情况下,preg_match_all给出一个二维数组,其中第一个索引对应于组,第二个索引对应于匹配项。在您的输出中,它会以相反的方式解释。因此,当存在多个匹配项时,第一对0和1是两个找到的匹配项的完整匹配项。第二对0和1是您在这两场比赛中捕获的。
因此,对于*,您首先获得完整的字符串作为匹配,最后一个字符作为捕获(标记为 的两个内容0),这是正确的。然后,由于*允许零宽度匹配,因此您会在字符串末尾得到另一个(空)匹配,以及一个空捕获。不过,我不确定为什么相应的JS'示例不包含额外的空字符串,因为String.match会做同样的事情。
对于{4},您只需得到两个匹配项 (Trol和olo!),就像在 JavaScript 情况下分别捕获l和!一样,这又完全没问题。