* Perl 6 中的量词
Posted
技术标签:
【中文标题】* Perl 6 中的量词【英文标题】:* quantifier in Perl 6 【发布时间】:2018-12-07 21:33:12 【问题描述】:这似乎是我在这里不明白的非常基本的东西。
为什么"babc"
不匹配/ a * /
?
> "abc" ~~ / a /
「a」
> "abc" ~~ / a * /
「a」
> "babc" ~~ / a * /
「」 # WHY?
> "babc" ~~ / a + /
「a」
【问题讨论】:
你的意思是/a*/
,它只是作为/ a * /
出现,因为我很确定正则表达式中的空格很重要,所以*
在``而不是a
....
@Artb 不,它们无关紧要,/a*/
给出了相同的结果。
【参考方案1】:
因为*
量词使前面的原子匹配零次或更多次。
「」
是任何字符串中/ a * /
的第一个匹配项。例如:
say "xabc" ~~ / a * . /; # OUTPUT: 「x」
都一样:
say "xabc" ~~ / (a+)? . /;
如果你把模式设置得更精确,你会得到另一个结果:
say "xabc" ~~ / x a * /; # OUTPUT: 「xa」
say "xabc" ~~ / a * b /; # OUTPUT: 「ab」
【讨论】:
这是有道理的——但是为什么"abc" ~~ / a * /
没有给出相同的结果呢?
@KeithThompson a*
模式(不是a*?
)将匹配一个或多个连续的a
s - 尽可能多。给它 zero a
s 以匹配它,它会 still 尽可能多地匹配(零)。无论哪种方式,它都匹配并且正则表达式完成,除非在a*
之后有更多的模式。如果有更多的模式,那么它也会尝试。如果 that 匹配,则正则表达式完成。如果不是,则正则表达式回溯并再次尝试,匹配少一个 a
以查看是否可行。如果失败,它会回溯并匹配少一个 a
等。
@KeithThompson 类似地,a*?
模式将节俭地匹配一个或多个连续的a
s——尽可能很少。匹配 zero a
s 比匹配最后没有 ?
的贪婪的 a*
更快乐。但是,如果正则表达式模式还有更多内容,那么它会继续。如果下一位失败,那么引擎会回溯并尝试匹配 more a
而不是更少,然后尝试模式的其余部分。如果它仍然失败,那么它会再次回溯等等。(这种回溯行为仅适用于regex
模式,而不是token
或rule
。/.../
文字是regex
。)
@raiph 当你使用a*
时,你的意思是零个或多个连续的a
s——一个或多个是a+
。无论输入如何,都可以保证像a*?
这样的节俭匹配提供零长度匹配。 say "cccc" ~~ /a*?/ # output: 「」
@donaldh 当然,a*
和 a+
是对的。我犯了一个愚蠢的错误。【参考方案2】:
这里的答案是正确的,我只是尝试以更连贯的形式呈现它们:
匹配总是从左边开始
正则表达式引擎总是从字符串的左边开始,并且更喜欢最左边的匹配而不是较长的匹配
*
匹配空字符串
正则表达式a*
匹配可以匹配字符串''
、'a'
、'aa'
等。
它总是喜欢它找到的最长的匹配,但它找不到比空字符串更长的匹配,它只会匹配空字符串。
把它放在一起
在'abc' ~~ /a*/
中,正则表达式引擎从位置0 开始,a*
匹配尽可能多的a,因此匹配第一个字符。
在'babc' ~~ /a*/
中,正则表达式引擎从位置0 开始,a*
只能匹配零个字符。它成功地做到了。由于整体匹配成功,没有理由在位置 1 再试一次。
【讨论】:
谢谢!唯一的问题是为什么它与标准 bashgrep
不同(echo babc | grep 'a*'
将匹配)?
正则表达式匹配,它只匹配空字符串。如果您执行say so 'babc' ~~ /a*/
,则显示为 True。
我的意思是传统的 grep 将匹配一个非空字符串(在这种情况下为a
)。那么在 Perl 6 中让它与众不同的想法是什么?
@EugeneBarsky 可能grep
底层的正则表达式引擎也在匹配空字符串,但grep
选择不显示它们。此外,grep
可能默认为多重匹配。所以echo babaac | grep 'a*'
,它显示类似“babaac”,对应于say "babaac" ~~ m:g/ a * /
,它显示(「」 「a」 「」 「aa」 「」 「」)
。
echo bbbb | grep 'a*'
也匹配,因此 grep 的行为是相同的。 Grep 显示匹配的行,而不是匹配项本身。以上是关于* Perl 6 中的量词的主要内容,如果未能解决你的问题,请参考以下文章