Perl 6 中正则表达式中 <> 和匿名数组的特殊含义
Special meaning of <> and anonymous arrays inside regex in Perl 6
在正则表达式之外,<> 的行为或多或少类似于单引号。我的肤浅理解似乎告诉我,在正则表达式中,<> 允许对代码进行评估和插值:
# Outside regex, <> acts like single quotes:
> 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」
因为正则表达式中允许使用数组变量,我怀疑 Perl 6 正则表达式引擎在数组周围有 <> 内部正则表达式时将数组扩展为 OR。
我还怀疑在用户定义的字符class、<[ ]>中,<>中的数组[]或多或少像匿名数组一样工作,类似于下面的@a,并且数组的内容(字符 class 中的字符)扩展为 OR。
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」
和 char class 扩展:
> 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 源代码(我现在真的尽量不要这样做)?
在正则表达式之外 <>
的行为类似于 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'
我建议阅读 Language: Quoting Constructs,因为这是一个更广泛的主题,无法在此处讨论。
这与 <>
在正则表达式中所做的几乎无关。
在正则表达式中使用 <>
在基本 Perl 6 代码中没有用,而 qw
在正则表达式中用处不大。所以这些字符起着双重作用,主要是因为 ASCII 中非字母和非数字字符很少。它唯一一次表现得像 qw
是紧跟在 <
之后的字符是空白字符。
在正则表达式内部,它可以被认为是将一些代码注入到正则表达式中;有点像宏或函数调用。
/<{ split ';', 'a;b;c' }>/;
/ [ "a" | "b" | "c" ] /;
( 请注意,|
同时尝试所有交替,而 ||
首先尝试最左边的一个,然后是下一个,等等。也就是说 ||
基本上可以工作|
在 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> /
/ [ "one" | "two" ] /
请注意 / @a /
也分解为相同的结构。
/ <?{ 1 > 0 }> /
# null regex always succeeds
/ [ '' ] /
/ <?{ 1 == 0 }> /
# try to match a character after the end of the string
# (can never succeed)
/ [ $ : . ] /
最后两个不太准确,但可能是一种有用的思考方式。
也用于调用正则表达式"methods".
grammar Foo {
token TOP { <alpha> } # calls Grammar.alpha and uses it at that point
}
如果你注意到我总是用 []
包围替换,因为它总是像一个独立的子表达式。
技术上 none 这些都是按照我展示的方式实现的,它只是一个更容易解释的理论模型。
在正则表达式中 <>
用于我倾向于称之为 "generalized assertions" 的内容。每当您使用正则表达式匹配某些内容时,您都会对字符串的外观做出一系列断言。如果所有断言都为真,则整个正则表达式匹配。例如,/ foo /
断言字符串 "foo" 出现在被匹配的字符串中; / f o* /
断言字符串应包含一个 "f" 后跟零个或多个 "o",等等
在任何情况下,对于一般化断言,Rakudo Perl 6 使用紧跟在 <
之后的字符来确定正在进行哪种断言。如果 <
之后的字符是字母(例如 <foo>
),则表示一个命名的子规则;如果 <
之后的字符是 {
,它是一个包含要插入到模式中的代码的断言(例如,<{ gen_some_regex(); }>
);如果 <
之后的字符是 [
,则它是一个字符 class;如果 <
之后的字符是 :
,那么它期望匹配 Unicode 属性(例如,<:Letter>
);如果 <
之后的字符是 ?
或 !
,您将分别得到正零宽度断言和负零宽度断言;等等
最后,在正则表达式之外,<>
充当 "quote words"。如果 <
后面的字符是空白字符,在正则表达式中,它也将作为一种 "quote words":
> "I'm a bartender" ~~ / < foo bar > /
「bar」
这是匹配的,就好像它是一个交替,即 < foo bar >
将匹配 foo
或 bar
之一,就好像你写了 foo | bar
。
在正则表达式之外,<> 的行为或多或少类似于单引号。我的肤浅理解似乎告诉我,在正则表达式中,<> 允许对代码进行评估和插值:
# Outside regex, <> acts like single quotes:
> 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」
因为正则表达式中允许使用数组变量,我怀疑 Perl 6 正则表达式引擎在数组周围有 <> 内部正则表达式时将数组扩展为 OR。
我还怀疑在用户定义的字符class、<[ ]>中,<>中的数组[]或多或少像匿名数组一样工作,类似于下面的@a,并且数组的内容(字符 class 中的字符)扩展为 OR。
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」
和 char class 扩展:
> 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 源代码(我现在真的尽量不要这样做)?
在正则表达式之外 <>
的行为类似于 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'
我建议阅读 Language: Quoting Constructs,因为这是一个更广泛的主题,无法在此处讨论。
这与 <>
在正则表达式中所做的几乎无关。
在正则表达式中使用 <>
在基本 Perl 6 代码中没有用,而 qw
在正则表达式中用处不大。所以这些字符起着双重作用,主要是因为 ASCII 中非字母和非数字字符很少。它唯一一次表现得像 qw
是紧跟在 <
之后的字符是空白字符。
在正则表达式内部,它可以被认为是将一些代码注入到正则表达式中;有点像宏或函数调用。
/<{ split ';', 'a;b;c' }>/;
/ [ "a" | "b" | "c" ] /;
( 请注意,|
同时尝试所有交替,而 ||
首先尝试最左边的一个,然后是下一个,等等。也就是说 ||
基本上可以工作|
在 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> /
/ [ "one" | "two" ] /
请注意 / @a /
也分解为相同的结构。
/ <?{ 1 > 0 }> /
# null regex always succeeds
/ [ '' ] /
/ <?{ 1 == 0 }> /
# try to match a character after the end of the string
# (can never succeed)
/ [ $ : . ] /
最后两个不太准确,但可能是一种有用的思考方式。
也用于调用正则表达式"methods".
grammar Foo {
token TOP { <alpha> } # calls Grammar.alpha and uses it at that point
}
如果你注意到我总是用 []
包围替换,因为它总是像一个独立的子表达式。
技术上 none 这些都是按照我展示的方式实现的,它只是一个更容易解释的理论模型。
在正则表达式中 <>
用于我倾向于称之为 "generalized assertions" 的内容。每当您使用正则表达式匹配某些内容时,您都会对字符串的外观做出一系列断言。如果所有断言都为真,则整个正则表达式匹配。例如,/ foo /
断言字符串 "foo" 出现在被匹配的字符串中; / f o* /
断言字符串应包含一个 "f" 后跟零个或多个 "o",等等
在任何情况下,对于一般化断言,Rakudo Perl 6 使用紧跟在 <
之后的字符来确定正在进行哪种断言。如果 <
之后的字符是字母(例如 <foo>
),则表示一个命名的子规则;如果 <
之后的字符是 {
,它是一个包含要插入到模式中的代码的断言(例如,<{ gen_some_regex(); }>
);如果 <
之后的字符是 [
,则它是一个字符 class;如果 <
之后的字符是 :
,那么它期望匹配 Unicode 属性(例如,<:Letter>
);如果 <
之后的字符是 ?
或 !
,您将分别得到正零宽度断言和负零宽度断言;等等
最后,在正则表达式之外,<>
充当 "quote words"。如果 <
后面的字符是空白字符,在正则表达式中,它也将作为一种 "quote words":
> "I'm a bartender" ~~ / < foo bar > /
「bar」
这是匹配的,就好像它是一个交替,即 < foo bar >
将匹配 foo
或 bar
之一,就好像你写了 foo | bar
。