动态提取字符串Perl / Regex的多个部分

时间:2016-03-03 16:57:07

标签: regex perl

所以这可能有一个非常简单的解决方案,但我在Perl中非常绿色....为简单起见,我将使用一个简单的例子:

# extract hours, minutes, seconds
$time =~ /(\d\d):(\d\d):(\d\d)/;  # match hh:mm:ss format
$hours = $1;
$minutes = $2;
$seconds = $3;

我正在编写的应用程序允许用户输入可能具有多个匹配的正则表达式字符串,如示例中所示。我正在寻找一种方法,根据用户输入的正则表达式了解我可以使用多少$<n>$parsed_response =~ /$block_start_regex/;。有没有办法看看在当前匹配过程中是否定义了$ 1,$ 2 .... $ n?我正在使用: $block_start_regex=qr/(\S+)\s+(\S+)\s+(\S+)/; 其中$ block_start_regex可以是return RedirectToAction("AdditionalInfo"); 或用户输入的任何内容.....

另外,如果我之前在9个变量的代码中匹配,那么下次运行正则表达式匹配时它们是否都会重新定义为未定义?

1 个答案:

答案 0 :(得分:5)

如果你匹配正则表达式,你可以捕获匹配&#39;成阵列:

my @matches = $time =~ /(\d\d):(\d\d):(\d\d)/g;  

然后会多次匹配,并且会发出“点击”字样。进入@matches数组。

所以以上面的例子为例:

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

my $str = "11:22:33 somefhunakdawer 14:32:17"; 

my @matches = $str =~ /(\d\d):(\d\d):(\d\d)/g;

print Dumper \@matches;

这将为您提供一个数组:

$VAR1 = [
          '11',
          '22',
          '33',
          '14',
          '32',
          '17'
        ];

虽然 - 你必须用3元素块读取数组。

或者 - 你可以分组&#39;你的捕获,具体取决于你所追求的:

my $str = "11:22:33 somefhunakdawer 14:32:17"; 
my $pattern = qr/(\d\d):(\d\d):(\d\d)/; 

my @matches = $str =~ m/($pattern)/g;

print Dumper \@matches;

这将给你:

$VAR1 = [
          '11:22:33',
          '11',
          '22',
          '33',
          '14:32:17',
          '14',
          '32',
          '17'
        ];

有点难以采用输入模式并且&#39;合并&#39;它,但你可以这样做:

my $str = "11:22:33 somefhunakdawer 14:32:17"; 
my $pattern = qr/\d\d:\d\d:\d\d/; 

my @matches = map {[ split /:/ ]} $str =~ m/($pattern)/g;

print Dumper \@matches;

这将选择$pattern的实例,但随后使用map将其拆分为分隔符,并将其拆分为子数组。因此我们得到:

$VAR1 = [
          [
            '11',
            '22',
            '33'
          ],
          [
            '14',
            '32',
            '17'
          ]
        ];

在这两种情况下,你需要更多的逻辑 - 你可以告诉你,如果你的输入中有3个捕获组,你的{{1}会有3的倍数}}。

如果你想动态检测,你可能会重复匹配:

@matches

第一次捕获(没有my $str = "11:22:33 somefhunakdawer 14:32:17"; my $pattern = qr/(\d\d):(\d\d):(\d\d)/; my @matches = $str =~ m/$pattern/; my $num_groups = @matches; @matches = $str =~ m/$pattern/g; while ( @matches ) { print "Group : ", join ("-", splice ( @matches, 0, $num_groups )),"\n"; } )告诉您此模式生成的捕获组数量。

然后运行第二次捕获 - 使用g - 重复捕获到数组中,然后从匹配列表中提取许多捕获组。

虽然注意 - 如果输入模式中存在可变捕获组,这种方法将失败 - 例如

g

有可选的&#39;秒&#39;匹配