0

我想写一个脚本,只要遇到正则表达式就可以返回结果。我猜我在编写正则表达式时遇到了一些困难。

我的输入文件的内容如下:

 Number a123;
     Number b456789 vit;
 alphabet fty;

我希望它会返回 a123 和 b456789 的结果,这是“Number”之后和之前(“\s”或“;”)的字符串。我尝试过使用下面的 cmd 行:

 my @result=grep /Number/,@input_file;
 print "@results\n";

我得到的结果如下所示:

  Number a123;
     Number b456789 vit;

Weareas 预期结果应如下所示:

a123
b456789

有人可以帮忙吗?

4

3 回答 3

3

Perlsgrep函数从列表中选择/过滤符合特定条件的所有元素。/Number/在您的情况下,您从@input_file数组中选择了与正则表达式匹配的所有元素。

Number要在使用此正则表达式后选择非空白字符串:

my $regex = qr{
  Number     # Match the literal string 'Number'
  \s+        # match any number of whitespace characters
  ([^\s;]+)  # Capture the following non-spaces-or-semicolons into $1
             # using a negated character class
}x;          # use /x modifier to allow whitespaces in pattern
             # for better formatting

我的建议是直接循环输入文件句柄:

while(defined(my $line = <$input>)) {
  $line =~ /$regex/;
  print "Found: $1" if length $1; # skip if nothing was found
}

如果必须使用数组,foreach最好使用 -loop:

foreach my $line (@input_lines) {
  $line =~ /$regex/;
  print "Found: $1" if length $1; # skip if nothing was found
}

如果您不想直接打印匹配项,而是将它们存储在数组中,push则将值放入循环内的数组中(两者都有效)或使用map函数。map 函数将每个输入元素替换为指定操作的值:

my @result = map {/$regex/; length $1 ? $1 : ()} @input_file;

或者

my @result = map {/$regex/; length $1 ? $1 : ()} <$input>;

map块内,我们将正则表达式与当前数组元素进行匹配。如果我们有一个匹配,我们返回$1,否则我们返回一个空列表。这会变得不可见,因此我们不会在@result. 这是不同的形式返回undef,什么会在你的数组中创建一个 undef 元素。

于 2012-09-04T03:46:25.193 回答
2

如果您的脚本旨在作为一个简单的过滤器,您可以使用

$ cat FILE | perl -nle 'print $1 if /Number\s+([^\s;]+)/'

或者

$ cat FILE | perl -nle 'for (/Number\s+([^\s;]+)/g) { print }'

如果在同一行上可以多次出现。

于 2012-09-04T03:44:35.663 回答
0
perl -lne 'if(/Number/){s/.*\s([a-zA-Z])([\d]+).*$/\1\2/g;print}' your_file

测试如下:

> cat temp
Number a123;
 Number b456789 vit;
 alphabet fty;


> perl -lne 'if(/Number/){s/.*\s([a-zA-Z])([\d]+).*$/\1\2/g;print}' temp
a123
b456789
> 
于 2012-09-04T09:03:17.403 回答