如何在perl中的正则表达式中访问命名捕获组中的值?

时间:2016-05-22 01:57:23

标签: regex perl

我正在尝试访问在名为子程序的命名捕获组中捕获的捕获数据:

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}。为什么这样,我该怎么做?

1 个答案:

答案 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

这样可以避免交替的成本。