正则表达式中的尖括号
2017-09-15
在正则表达式外面, <>
表现的更像单引号。我浅薄的认知告诉我, 在正则表达式内部, <>
允许求值和代码插值:
# 在正则表达式外面, <> 表现得像单引号:
> my $x = <{"one"}>
{"one"}
> $x.WHAT
(Str)
# inside regex, <> evaluates and interpolates:
> my $b="one";
one
> say "zonez" ~~ m/ <{$b}> / # evaluates {$b} then quotes: m/ one /
「one」
> say "zonez" ~~ m/ <$b> / # interpolates and quotes without {}
「one」
因为在正则表达式中允许有数组变量, 所以我猜测 raku 正则引擎在数组两边含有 <>
时将数组展开成 OR 了。我还猜测在用户自定义的字符类 <[]>
中, <>
中的 []
有点像匿名数组, 和下面的 @a
类似, 并且数组(字符类中的字符)的内容扩展为 OR’s:
my @a = $b, "two";
[one two]
> so "zonez" ~~ m/ @a /;
True
> say "ztwoz" ~~ m/ <{[$b, "two"]}> / # {} to eval array, then <> quotes
「two」
> say "ztwoz" ~~ m/ <{@a}> /
「two」
> say "ztwoz" ~~ m/ <@a> /
「two」
> say "ztwoz" ~~ m/ one || two / # expands @a into ORs: [||] @a;
# [||] is a reduction operator;
「two」
还有字符类展开:
> say "ztwoz" ~~ m/ <[onetw]> / # like [||] [<o n e t w>];
「t」
> say "ztwoz" ~~ m/ o|n|e|t|w /
「t」
> my @m = < o n e t w >
[o n e t w]
> say "ztwoz" ~~ m/ @m /
「t」
我还没有读 Rakudo 源代码, 并且我的理解也有限。
所以, <>
在正则中有点儿特殊吧?我是不是应该学习下 Rakudo 源代码? 谢谢。
Answer
在正则外面,<>
表现得像 qw<>
, 那就是引号和分隔空格。
say <a b c>.perl; # ("a", "b", "c")
它可以被展开为:
q :w 'a b c'
Q :q :w 'a b c'
Q :single :words 'a b c'
推荐阅读 语言:引号结构 这个更深入的主题。
这个和正则表达式中的 <>
没有关系。
在简单的 Raku 代码中, <>
在正则中并不是那么有用, 并且 qw
在正则中也不是那么有用。
在正则中可以插入某些代码到正则表达式中; 这有点像宏, 或函数调用。
/<{ split ';', 'a;b;c' }>/;
/ [ "a" | "b" | "c" ] /;
# 'b' ~~ m/<{ split ';', 'a;b;c' }>/;
# say "zzonezz" ~~ m/ <{ say "foo"; "one";}> /
(注意 |
会同时尝试所有的分支而 ||
首先尝试最左侧的分支, 紧接着是下一个, 等等。即 ||
和 Perl 5 和 PCRE 中的 |
作用类似。)
/<:Ll - [abc]>/
/ [d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z] / # plus other lowercase letters
注意, / @a /
会把数组中的每个元素都作为一个分支:
/ <@a> /
/ [ "one" | "two" ] /
/ <?{ 1 > 0 }> /
# null regex always succeeds
/ [ '' ] /
/ <?{ 1 == 0 }> /
# try to match a character after the end of the string
# (can never succeed)
/ [ $ : . ] /
最后那俩不是很准确, 但是是一种思路。
<>
还经常用于调用 regex “methods”.
grammar Foo {
token TOP { <alpha> } # calls Grammar.alpha and uses it at that point
}