Regex 在perl中用换行符拆分正则表达式匹配项

Regex 在perl中用换行符拆分正则表达式匹配项,regex,perl,subroutine,perl-data-structures,Regex,Perl,Subroutine,Perl Data Structures,我试图从一个目录中读取文件并打印出regexp匹配项, 试图匹配 <110> *everything here* <120> 但是,当我尝试通过换行来拆分此内容并使用|进行连接时,我没有得到所需的输出 Applicant : SCHALLY, ANDREW V. | CAI, REN ZHI | ZARANDI, MARTA 我的当前输出仅为 | ZARANDI, MARTA 有人能看到明显的错误吗 #!/usr/bin/perl u

我试图从一个目录中读取文件并打印出regexp匹配项, 试图匹配

 <110> 
    *everything here*
 <120>
但是,当我尝试通过换行来拆分此内容并使用|进行连接时,我没有得到所需的输出

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;
}
替换

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

原始代码的问题是$1未更改,即如果regexp不匹配,则从上一个文件中保留


如果这还不能解决问题,那么请再次检查并确保您的$U字符串值正确。您的连接+拆分行看起来正确。

我运行了您的代码并获得

|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);

@pts是正确的,regex捕获变量不会重置为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>

你的实际投入是什么?产量呢?您的“整个文件”只匹配一次-这是您想要的吗?输入是多个文件,我将每个文件全局化并在整个文件上使用正则表达式,是的,每个文件一次就足够了/\s*?:\r?\n+\s*/使用此正则表达式拆分成功了正则表达式在拆分语句中捕获的内容是什么?@Stacked for life-它进行内部修剪。呃,split语句中的capture插入元素中捕获的内容。我很想在列表上下文中进行regexp测试,并直接分配匹配项,而不是使用$。这样,如果匹配失败,则结果是未定义的。
|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);
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