我想编写一个脚本,只要正则表达式相遇就可以返回结果。我在编写正则表达式时遇到了一些困难。
我输入文件的内容如下:
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;
Wheareas的预期结果应如下所示:
a123
b456789
有人可以为此提供帮助吗?
答案 0 :(得分:3)
Perls grep
函数选择/过滤列表中与特定条件匹配的所有元素。在您的情况下,您从/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
- 循环:
foreach my $line (@input_lines) {
$line =~ /$regex/;
print "Found: $1" if length $1; # skip if nothing was found
}
如果您不想直接打印匹配项,而是将它们存储在数组中,请将push
值放入循环内的数组中(两者都有效)或使用map
函数。 map函数用指定操作的值替换每个input元素:
my @result = map {/$regex/; length $1 ? $1 : ()} @input_file;
或
my @result = map {/$regex/; length $1 ? $1 : ()} <$input>;
在map
块内,我们将正则表达式与当前数组元素进行匹配。如果匹配,我们会返回$1
,否则我们会返回空列表。这会变得扁平化为隐形,因此我们不会在@result
中创建条目。这是返回undef
的不同形式,会在数组中创建一个undef元素。
答案 1 :(得分:2)
如果你的脚本是一个简单的过滤器,你可以使用
$ cat FILE | perl -nle 'print $1 if /Number\s+([^\s;]+)/'
或
$ cat FILE | perl -nle 'for (/Number\s+([^\s;]+)/g) { print }'
如果在同一行上可能有多个出现。
答案 2 :(得分: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
>