拆分正则表达式匹配perl中的换行符

时间:2014-11-05 20:30:31

标签: regex perl subroutine perl-data-structures

我正在尝试从目录中传输文件并打印出正则表达式匹配, 试图匹配

 <110> 
    *everything here*
 <120>

我的比赛将是

SCHALLY, ANDREW V. 
CAI, REN ZHI
      ZARANDI, MARTA

然而,当我尝试通过换行分割它并使用&#34; |&#34;加入时,我没有得到所需的输出

Applicant :  SCHALLY, ANDREW V. | CAI, REN ZHI | ZARANDI, MARTA

我目前的输出只是

 |        ZARANDI, MARTA

有人可以看到任何明显的错误吗?

#!/usr/bin/perl
use warnings;
use strict;
use IO::Handle;

open (my $fh, '>', '../logfile.txt')  || die "can't open logfile.txt";
open (STDERR, ">>&=", $fh)         || die "can't redirect STDERR";
$fh->autoflush(1);



my $input_path = "../input/";
my $output_path = "../output/";
my $whole_file;

opendir INPUTDIR, $input_path or die "Cannot find dir $input_path : $!";
my @input_files = readdir INPUTDIR;
closedir INPUTDIR;

foreach my $input_file  (@input_files) 
{   
    $whole_file = &getfile($input_path.$input_file); 
    if ($whole_file){
        $whole_file =~  /[<][1][1][0][>](.*)[<][1][2][0][>]/s ;
        if ($1){
            my $applicant_string = "Applicant : $1";
            my $op = join( "|", split("\n", $applicant_string) );
            print $op; 
        }
    }
}

close $fh;




sub getfile {
    my $filename = shift;
    open F, "< $filename " or die "Could not open $filename : $!" ;
    local $/ = undef; 
    my $contents = <F>;
    close F;
    return $contents;
}

编辑1

我在单个文件上使用代码

    #!/usr/bin/perl
use warnings;
use strict;
use IO::Handle;


my $input_file = "01.txt-WO13_090919_PD_20130620";
my $input_path = "../input/";

my $whole_file = &getfile($input_path.$input_file); 


if ($whole_file =~  /[<][1][1][0][>](.*)[<][1][2][0][>]/s ) {
        print $1;
            my @split_string = split("\n", $1);
            my $new_string =  join("|", @split_string) ;
            print "$new_string \n";
}



sub getfile {
    my $filename = shift;
    open F, "< $filename " or die "Could not open $filename : $!" ;
    local $/ = undef; 
    my $contents = <F>;
    close F;
    return $contents;
}

输出

  Chen, Guokai
       Thomson, James
       Hou, Zhonggang

        Hou, Zhonggang

3 个答案:

答案 0 :(得分:2)

替换

$whole_file =~  /[<][1][1][0][>](.*)[<][1][2][0][>]/s ;
if ($1) {

if ($whole_file =~ /[<][1][1][0][>](.+)[<][1][2][0][>]/s) {

如果正则表达式不匹配,原始代码的问题是$1未更改(即保留在上一个文件中)。

如果这不能解决问题,请仔细检查并确保$applicant_string具有正确的值。您的加入+分割线看起来是正确的。

答案 1 :(得分:1)

我运行你的代码并获得

|SCHALLY, ANDREW V. |CAI, REN ZHI|      ZARANDI, MARTA

这非常接近。您需要做的就是在加入之前修剪空格。所以替换这个

 my @split_string = split("\n", $1);
 my $new_string =  join("|", @split_string) ;

有了这个:

 my @split_string = split("\n", $1);
 my @names;
 foreach my $name ( @split_string ) {
   $name =~ s/^\s*(.*)\s*$/$1/;
   next if $name =~ /^$/; 
   push @names, $name;
 }

 my $new_string =  join("|", @names);

答案 2 :(得分:1)

@pts是正确的,正则表达式捕获变量不会重置为UNDEF
在负面匹配时,看起来他们保留了他们的最后价值。

所以他的解决方案应该适合你。使用if ( $whole_file =~ // ) {}表单。

除此之外,您可以通过执行类似的操作来稍微清理操作

use strict;
use warnings;

$/ = undef;
my $whole_file = <DATA>;

if ( $whole_file =~ /[<][1][1][0][>](.*)[<][1][2][0][>]/s )
{
    my $applicant_string = $1;
    $applicant_string =~ s/^\s+|\s+$//g;
    my $op = "Applicant : " . join( " | ", split( /\s*\r?\n\s*/, $applicant_string) );
    print $op; 
}

__DATA__

          <110>


  SCHALLY, ANDREW V. 
CAI, REN ZHI
      ZARANDI, MARTA

  <120>

输出:

Applicant : SCHALLY, ANDREW V. | CAI, REN ZHI | ZARANDI, MARTA