Perl:如何以结构化的方式获取多个正则表达式?

Maz*_*zze 2 regex perl regex-group

我试图在任意字符串中获取一组模式的所有出现,就像这样:

my $STRING = "I have a blue cat. That cat is nice, but also quite old. She is always bored.";

foreach (my @STOPS = $STRING =~ m/(?<FINAL_WORD>\w+)\.\s*(?<FIRST_WORD>\w+)/g ) {

  print Dumper \%+, \@STOPS;
}
Run Code Online (Sandbox Code Playgroud)

但结果不是我所期望的,我也不完全明白为什么:

$VAR1 = {
          'FINAL_WORD' => 'old',
          'FIRST_WORD' => 'She'
        };
$VAR2 = [
          'cat',
          'That',
          'old',
          'She'
        ];
$VAR1 = {
          'FINAL_WORD' => 'old',
          'FIRST_WORD' => 'She'
        };
$VAR2 = [
          'cat',
          'That',
          'old',
          'She'
        ];
$VAR1 = {
          'FINAL_WORD' => 'old',
          'FIRST_WORD' => 'She'
        };
$VAR2 = [
          'cat',
          'That',
          'old',
          'She'
        ];
$VAR1 = {
          'FINAL_WORD' => 'old',
          'FIRST_WORD' => 'She'
        };
$VAR2 = [
          'cat',
          'That',
          'old',
          'She'
        ];
Run Code Online (Sandbox Code Playgroud)

如果没有更好的解决方案,我可以@STOPS接受最终的内容并省略循环。但我更愿意分别获得每对比赛,我看不出有什么办法。

但是为什么循环执行多次呢?

预先感谢您,并问候,

马泽

Håk*_*and 6

您需要使用while循环而不是for循环:

while ($STRING =~ m/(?<FINAL_WORD>\w+)\.\s*(?<FIRST_WORD>\w+)/g ) {
    print Dumper \%+;
}
Run Code Online (Sandbox Code Playgroud)

输出

$VAR1 = {
          'FIRST_WORD' => 'That',
          'FINAL_WORD' => 'cat'
        };
$VAR1 = {
          'FIRST_WORD' => 'She',
          'FINAL_WORD' => 'old'
        };
Run Code Online (Sandbox Code Playgroud)

for循环收集所有的比赛,在一次@STOPS%+设定为最后的全局匹配。该while循环允许您分别遍历每个全局匹配。

根据perldoc perlretut

修饰符/g代表全局匹配,允许匹配操作符在一个字符串内尽可能多地匹配。在标量上下文中,对字符串的连续调用/g将从一个匹配跳到另一个匹配,随着它的进行跟踪在字符串中的位置。您可以使用该pos()函数获取或设置位置。