在比赛次数变化时获得所有比赛

时间:2014-09-20 06:05:19

标签: regex perl lookahead

我有变量:

$line = "print      var1,   var2, var3";

var1将始终存在,但其他var可能不存在。

我想提取var1以及可能出现的任何其他var

我目前正在使用以下内容:

$line = "print      var1,   var2, var3";

if ($line =~ /\s*print\s*([A-Za-z0-9]+)(?=\s*,\s*([A-Za-z0-9]+))/){
    print "$1\n";

    while ($line =~ /\s*print\s*([A-Za-z0-9]+)(?=\s*,\s*([A-Za-z0-9]+))/g){
        print "$2\n";
}

不确定我是否过度复杂......但结果很简单:

var1
var2

而不是:

var1
var2
var3

任何人都知道如何实现这一目标?

3 个答案:

答案 0 :(得分:1)

保持简单。

使用正则表达式确定要解析的行,然后使用split分隔值:

use strict;
use warnings;

while ( my $line = <DATA> ) {
    if ( $line =~ /^print\s+(.*)/ ) {
        my @vars = split /,\s*/, $1;
        print "@vars\n";
    }
}

__DATA__
print      var1,   var2, var3

输出:

var1 var2 var3

答案 1 :(得分:1)

当前正则表达式的问题在于您只有两个捕获组。最简单的方法是使用尽可能多的捕获组作为变量,但这并不实用。下一个最简单的方法是匹配所有变量,然后用逗号分隔。

但是如果您仍想在一个正则表达式中执行此操作,则可以使用在行的开头或上一个匹配结束时匹配的\G锚点。理解它可能有点复杂(你可以阅读更多here),但这里是如何使用它来获得你想要的东西:

$line = "print      var1,   var2, var3";

if ($line =~ /\s*print\s*([A-Za-z0-9]+)(?=\s*,\s*([A-Za-z0-9]+))/){
    print "$1\n";

    @lines = $line =~ /\s*(?:print|(?!^)\G)\s+([A-Za-z0-9]+)(?:,|$)/g;
    $result = join("\n", @lines);
    print "$result\n"
}

这个正则表达式基本上可以在一次匹配中获得所有变量。

答案 2 :(得分:0)

(?=(var\d+))

使用此。这将提供所有var。

您的正则表达式不适用于所有情况。它会搜索print var后面跟var。因此,如果print var没有var,则无效{{1}}在它之前。

参见演示。

http://regex101.com/r/pD5sV6/12