我正在尝试访问在名为子程序的命名捕获组中捕获的捕获数据:
use strict;
use warnings;
"this is a test" =~ /(?!)
(?<isa>is\s+a)
| (?&isa)\s
(?<test>test)/x;
print "isa: $+{isa}\ntest: $+{test}"
这是另一次尝试:
use strict;
use warnings;
"this is a test" =~ /(?!)
(?<isa_>(?<isa>is\s+a))
| (?&isa_)\s
(?<test>test)/x;
print "isa: $+{isa}\ntest: $+{test}"
我似乎无法填充$ + {isa}。为什么这样,我该怎么做?
答案 0 :(得分:0)
由于您使用(?!)
强制第一个分支失败,因此定义的命名捕获组(?<isa>...)
不会捕获任何内容(但定义为子模式)。
只有第二个分支成功,但是这个分支并没有为该组捕获任何内容&#34; isa&#34;,它只使用子模式别名(?&isa_)
。
您的第一个示例返回警告:
Reference to nonexistent named group in regex
因为&#34; isa _&#34;没有定义。
[编辑]你改变了你的&#34; isa _&#34; to&#34; isa&#34;在你的第一个例子中,但是对于这个新版本,没有理由在&#34; isa&#34;中捕获任何内容。命名组。
你的第二个例子不会填充&#34; isa&#34;同样,因为捕获组仅在定义它们的地方捕获事物,而不是在其他地方捕获(即使isa_
引用了组isa
。)
原因是Perl不会在递归中存储捕获(仅保留地面级别的捕获)。您可以使用此示例对其进行测试:
"this is a test" =~ /
(?!)
(?<isa_>
(?<isa> is \s+ a)
(?{print "isa in recursion: $+{isa}\n"})
)
|
(?&isa_) \s (?<test> test )
/x;
print "isa: $+{isa}\ntest: $+{test}"
但是,你可以写:
"this is a test" =~ /
(?!) (?<isa_> is \s+ a )
|
(?<isa> (?&isa_) ) \s (?<test> test )
/x;
print "isa: $+{isa}\ntest: $+{test}";
但是在这里,命名的捕获&#34; isa&#34;在地面上。
注意:您可以使用(?!)
语法,而不是使用(?(DEFINE)...)
使模式失败并进行更改:
/(?(DEFINE)
(?<isa_> (?<isa> is \s+ a) )
)
(?&isa_) \s (?<test> test )
/x
或者这个:
/(?<isa_> (?<isa> is \s+ a) ){0}
(?&isa_) \s (?<test> test )
/x
这样可以避免交替的成本。