我必须从a file读取行并将它们存储在Perl中的散列中。其中许多行在开始时都有特殊的字符序列,我需要在存储之前将其删除。这些字符序列是
| || ### ## @@||
例如,如果是||https://ads
,我需要https://ads
;如果###http
,我需要http
。
我需要排除这些字符序列。我想通过将所有字符序列排除在数组中然后检查该行是否以这些字符序列开头并删除它们来实现此目的。有什么好办法呢?
我走得很远:
our $ad_file = "C:/test/list.txt";
our %ads_list_hash = ();
my $lines = 0;
# List of lines to ignore
my @strip_characters = qw /| || ### ## @@||/;
# Create a list of substrings in the easylist.txt file
open my $ADS, '<', $ad_file or die "can't open $ad_file";
while(<$ADS>) {
chomp;
$ads_list_hash{$lines} = $_;
$lines ++;
}
close $ADS;
如果存在任何一行,我需要添加逻辑以从每行的开头删除@strip_characters
。
答案 0 :(得分:4)
对于任务来说可能有点过于复杂和一般,但仍然......
my $strip = join "|", map {quotemeta} @strip_characters;
# avoid bare [] etc. in the RE
# ... later, in the while()
s/^(?:$strip)+//o;
# /o means "compile $strip into the regex once and for all"
答案 1 :(得分:3)
为什么不用正则表达式来做?像
这样的东西$line =~ s/^[#@ |]+//;
应该有用。
答案 2 :(得分:1)
如果您要删除字符列表(根据您的标题),则可以使用非常简单的正则表达式。
在循环中,添加以下正则表达式
while( <$ADS> ) {
chomp;
s/^[#@ \|]+//;
$ads_list_hash{$lines++} = $_;
}
注意管道charachter('|')被删除。 但是,您似乎要删除表达式列表。您可以执行以下操作
while( <$ADS> ) {
chomp;
s/^((\|)|(\|\|)|(###)|(##)|(@@\|\|))+//;
$add_list_hash{$lines++} = $_;
}
你说表达式列表存储在一个或多个数组中。在示例代码中,使用'qw'创建此数组。如果在编译时未知表达式列表,则可以在变量中构建正则表达式,并使用它。
my @strip_expression = ... // get an array of strip expressions
my $re = '^((' . join(')|(',@strip_expression) . '))+';
然后,在循环中使用以下语句: S / $重新//;
最后,关于代码可以说一个与问题无关的事情:使用Array代替Hash,将整数映射到一组字符串会更合适。除非你有其他要求,否则最好:
our @ads_list; // no need to initialize the array (or the hash) with empty list
...
while( <$ADS> ) {
chomp;
s/.../;
push @ads_list, $_;
}
答案 3 :(得分:1)
$ads_list_hash{$lines} = $_;
$lines ++;
不要那样做。如果需要数组,请使用数组:
push @ads_lines, $_;
Shawn的编程规则#7:创建数据结构时:如果保留顺序很重要,请使用数组;否则使用哈希。
答案 4 :(得分:0)
因为替换返回他们是否做了任何事情你可以使用a 替换为您的模式搜索字符串,如果存在则删除它。
while( <$ADS> ) {
next unless s/^\s*(?:[#]{2,3}|(?:@@)?[|]{1,2})\s*//;
chomp;
$ads_list_hash{$lines} = $_;
$lines ++;
}