过去两周我一直在学习perl。我一直在为我的学校项目写一些perl脚本。我需要为多个字符串解析一个文本文件。我搜索了perl论坛并获得了一些信息。下面的函数解析一个字符串的文本文件并返回结果。但是我需要脚本来搜索文件中的多个字符串。
use strict;
use warnings;
sub find_string {
my ($file, $string) = @_;
open my $fh, '<', $file;
while (<$fh>) {
return 1 if /\Q$string/;
}
die "Unable to find string: $string";
}
find_string('filename', 'string');
现在,例如,如果文件包含多个带有正则表达式的字符串,如下所示
"testing"
http://www.yahoo.com =1
http://www.google.com=2
我希望该函数能够搜索多个字符串,例如
find_string('filename', 'string1','string2','string3');
请有人可以解释我如何做到这一点。这会非常有帮助
答案 0 :(得分:2)
在这里快速完成这个:
您现在传递一个文件的名称和一个字符串。如果你传递多个字符串怎么办:
if ( find_string ( $file, @strings ) ) {
print "Found a string!\n";
}
else {
print "No string found\n";
}
..
sub find_string {
my $file = shift;
my @strings = @_;
#
# Let's make the strings into a regular expression
#
my $reg_exp = join "|" ,@strings; # Regex is $string1|$string2|$string3...
open my $fh, "<", $file or die qq(Can't open file...);
while ( my $line = <$fh> ) {
chomp $line;
if ( $line =~ $reg_exp ) {
return 1; # Found the string
}
}
return 0; # String not found
}
我即将参加一个会议,所以我甚至没有对此进行过测试,但这个想法就在那里。一些事情:
quotemeta
命令,也可以在每个字符串之前和之后使用\Q
和\E
。use autodie
来处理无法打开的文件。然后,您不必检查您的公开声明(就像我上面所做的那样)。$fh
)。我不会通过子程序打开你的文件,而是传入一个标量文件句柄。这将允许您处理主程序中的无效文件问题。这是标量文件句柄的一大优势:它们可以很容易地传递给子程序并存储在类对象中。#! /usr/bin/env perl
#
use strict;
use warnings;
use autodie;
use feature qw(say);
use constant {
INPUT_FILE => 'test.txt',
};
open my $fh, "<", INPUT_FILE;
my @strings = qw(foo fo+*o bar fubar);
if ( find_string ( $fh, @strings ) ) {
print "Found a string!\n";
}
else {
print "No string found\n";
}
sub find_string {
my $fh = shift; # The file handle
my @strings = @_; # A list of strings to look for
#
# We need to go through each string to make sure there's
# no special re characters
for my $string ( @strings ) {
$string = quotemeta $string;
}
#
# Let's join the stings into one big regular expression
#
my $reg_exp = join '|', @strings; # Regex is $string1|$string2|$string3...
$reg_exp = qr($reg_exp); # This is now a regular expression
while ( my $line = <$fh> ) {
chomp $line;
if ( $line =~ $reg_exp ) {
return 1; # Found the string
}
}
return 0; # String not found
}
autodie
在我无法打开文件时处理问题。无需检查。open
中有三个参数。这是首选方式。$fh
,它允许我将其传递给我的find_string
子例程。在主程序中打开文件,我可以在那里处理读错误。@strings
并使用quotemeta
命令自动转义特殊的正则表达式字符。$string
时,它实际上会修改@strings
数组。qr
创建正则表达式。/foo|fo\+\*o|bar|fubar/
。fooburberry
将与foo
匹配。你想要那个,或者你想要字符串是整个单词吗?答案 1 :(得分:0)
我很高兴在您的脚本中看到use strict
和use warnings
。这是一种基本的方法。
use strict;
use warnings;
sub find_string {
my ($file, $string1, $string2, $string3) = @_;
my $found1 = 0;
my $found2 = 0;
my $found3 = 0;
open my $fh, '<', $file;
while (<$fh>) {
if ( /$string1/ ) {
$found1 = 1;
}
if ( /$string2/ ) {
$found2 = 1;
}
if ( /$string3/ ) {
$found3 = 1;
}
}
if ( $found1 == 1 and $found2 == 1 and $found3 == 1 ) {
return 1;
} else {
return 0;
}
}
my $result = find_string('filename', 'string1'. 'string2', 'string3');
if ( $result == 1 ) {
print "Found all three strings\n";
} else {
print "Didn't find all three\n";
}
答案 2 :(得分:0)
我认为您可以先将文件内容存储在数组中,然后grep数组中的输入。
use strict;
use warnings;
sub find_multi_string {
my ($file, @strings) = @_;
my $fh;
open ($fh, "<$file");
#store the whole file in an array
my @array = <$fh>;
for my $string (@strings) {
if (grep /$string/, @array) {
next;
} else {
die "Cannot find $string in $file";
}
}
return 1;
}