看了flw给出的解决方法:
这是面向行处理的一种轻量级解决方法。
比那些对整个文件进行模式匹配的方法不知优雅了要多少倍。
$start 表示开始标记的模式,$end 表示结束标记的模式,
if ( (/$start/ .. /$end/) and !/$end/ ){
表示需要开始和结束之间的,但不需要结束的那一行。
但是问题来了,若模式匹配是不严格的,即:start和end是同一性质的,如一段文字,如下:
>
reo
sot
>
tin
>12
是以开头一个>作为标志。现在要取出每一个>及其后的文字,该如何处理?另外,最后一个是例外,如何解决?大家来讨论下吧。
use strict;
use Data::Dumper;
my $records = {}; # reference to hash
my $count = 0; # counter for normal key record
my $key = ''; # hash key
while () {
chomp;
if (/^>(.*)/) { # pattern match beginning with > (or followed by string)
if ($1) { # matsched followed by char and put it as special key
$key = 'specialKey_'. $1;
$records->{$key} = []; # initial ref. array
} else { # put counter as key
$key = 'count_' . ++$count;
}
} else {
# put all rest blocks after line ^> into a ref. array
push @{$records->{$key}}, $_;
}
}
# display data structures:
print Dumper $records;
__DATA__
>
reo
sot
>
tin
>12
Output data records:
$VAR1 = {
'count_1' => [
'reo',
'sot'
],
'count_2' => [
'tin'
],
'specialKey_12' => []
};
============================================
原帖由
forlorngenius 于 2008-9-22 21:32 发表
range operator 除了有两个点 .. 还有 三个点 ...
呵呵。这个还没有听说过,有时间的话请详细指教。。。
另外,我已经解决了。用的笨方法。这里贴上,或许能供需要之人参考:
#!/usr/bin/perl
$file=shift;
$to_file=shift;
open(TXT, $file) || die "can't open $!";
open(TXT2,">$to_file") or die "error $!";
while(
){
$content=$_;
if(/^>\d*[\r|\n]+/){
$_='';
$count=1;
}
if($count==1 ){
if(/^>\d+.+\w+/){
$count=0;}
}
if($count==1){
$content='';}
print TXT2 $content;
}
close(TXT);
close(TXT2);
提问只是简略,具体要求是:如发现一段是以>或者>\d+开头,而后面没有别的东西,则认为非法而删除。程序并不难,关键是逻辑。多谢大家的回答,希望有好的解决方法。
阅读(1842) | 评论(0) | 转发(0) |