2

我在 Perl 中有一个这样的正则表达式:

\s{2,}(?<name>(\S+\s)*\S+)\s{2,}

有没有办法可以验证$+{name}正则表达式中命名捕获的长度?

我只想匹配具有最大提供长度的值。

例如,我希望$+{name}最多 27 个字符。

我认为这种情况可以使用环视来完成,但我对这种方法还不是很熟悉。

这是一个例子:

我有这个数据:

ROTINSON, JABON                                          0.000
CHUNG, TSONH-HIW                                                           0.000
ROBINSONS, VISTOR R                                                                 0.000

您可以看到的名称将与 ((\S+\s)*\S+) 匹配,并且我希望我的正则表达式尽可能准确地捕获 27 个字符,因为我认为这是该列需要的最大长度。

您看到的数字应该在不同的列中,我想确切地找出必须在一列中添加哪个值,依此类推。这个文件不是一个固定宽度的文件,所以不是所有的值都会被相同数量的空格完全分开。会有一些小的变化。

到目前为止,我将它用于我的比赛,但没有按我的意愿工作:

/^\s{0,8}(?P<name>(\S+\s){0,5}\S+)
\s{10,70}(?P<value>\d+\.\d+)
\s*$/xi
4

2 回答 2

4

正则表达式并不是解决所有问题的灵丹妙药,在这种情况下它们是错误的选择。您应该将字符串拆分为多个空格字符,并拒绝超长的子字符串。

这个程序演示了它:

use strict;
use warnings;
use 5.010;

my $st = '  aaa aa aa  2long 2long 2long 2long 2long  bb bbb bb  cc cc ccc  ';

say for grep { $_ and length $_ <= 27 } split /\s{2,}/, $st;

输出

aaa aa aa
bb bbb bb
cc cc ccc
于 2013-09-17T12:09:04.997 回答
1

利用:

use strict;
use warnings;
use 5.010;

my $re = qr/\s{2,}(?=.{1,27}\s\s+)(?=(?<name>(\S+\s)*\S+))/;
while(<DATA>) {
    chomp;
    /$re/;
    say /$re/ ? "OK : $_, name=$+{name}" : "KO : $_";
}
__DATA__
aa  12345 67890  bb
aa  12345 678901234 56789012345 678  bb

输出:

OK : aa  12345 67890  bb, name=12345 67890
KO : aa  12345 678901234 56789012345 678  bb
于 2013-09-17T12:25:11.663 回答