Perl:如何匹配整个文本中的数据
Perl : How to match data in entire text
在下面的代码中,我尝试使用 Input File 1
中的数据来编辑 Input File 2
中的数据。但问题是当可能的匹配文本位于最后一个以外的任何地方时,代码无法匹配或替换,向右。
你能帮我想出在整个文本中匹配它的方法吗?
我对编码还是个新手,所以如果您发现任何其他可能的改进,我将非常感谢您的指导。
输入文件 1
Saint st
Saint saint
Saint st.
Saint snt
Saint snt.
Hotel htl
Hotel htl.
Road rd
Road rd.
输入文件 2
Part.Name.
Gordon house st
Gordon saint house
Gordon st. house
Gordon snt house
Gordon snt. house
htl palace
htl. Indiana
nuav rd hotel
dankei hotel rd.
代码从这里开始
use strict;
use warnings;
open (my $fh1, "< $filename1") or die $!;
my @incomin_data1=<$fh1>;
my $array_length1=$#incomin_data1;
my @key; my @value;
for (my $count=0;$count<=$array_length1;$count++)
{($key[$count],$value[$count])=split /,/,$incomin_data1[$count];}
my $key_length=$#key;
open (my $fh2, "< $filename2") or die $!;
my @incomin_data2=<$fh2>;
my $array_length2=$#incomin_data2;
for (my $count2=0;$count2<=$array_length2;$count2++)
{ for (my $count3=0;$count3<=$key_length;$count3++)
{ my $ky=$key[$count3];
my $val=$value[$count3];
if ($incomin_data2[$count2]=~/\s?$val\s?/g)
{ $incomin_data2[$count2]=~s/$val/$ky/; }}}
print "\n\n",@incomin_data2;
我能为您做的最好的就是简单地编写一个解决方案。您自己的代码无法恢复。
use strict;
use warnings;
my ($file1, $file2) = @ARGV;
my %abbrevs;
open my $fh, '<', $file1 or die $!;
while (<$fh>) {
chomp;
my ($phrase, $abbrev) = split /,/;
if ( exists $abbrevs{$abbrev} ) {
die sprintf 'Abbreviation "%s" already assigned to "%s"', $abbrev, $phrase;
}
$abbrevs{$abbrev} = $phrase;
}
my $re = join '|', map quotemeta, sort { length $b <=> length $a } keys %abbrevs;
$re = qr/$re/;
open $fh, '<', $file2 or die $!;
while (<$fh>) {
s/(?<![\w.])($re)(?![\w.])/$abbrevs{}/g;
print;
}
输出
Part.Name.
Gordon house Saint
Gordon Saint house
Gordon Saint house
Gordon Saint house
Gordon Saint house
Hotel palace
Hotel Indiana
nuav Road hotel
dankei hotel Road
在下面的代码中,我尝试使用 Input File 1
中的数据来编辑 Input File 2
中的数据。但问题是当可能的匹配文本位于最后一个以外的任何地方时,代码无法匹配或替换,向右。
你能帮我想出在整个文本中匹配它的方法吗?
我对编码还是个新手,所以如果您发现任何其他可能的改进,我将非常感谢您的指导。
输入文件 1
Saint st
Saint saint
Saint st.
Saint snt
Saint snt.
Hotel htl
Hotel htl.
Road rd
Road rd.
输入文件 2
Part.Name.
Gordon house st
Gordon saint house
Gordon st. house
Gordon snt house
Gordon snt. house
htl palace
htl. Indiana
nuav rd hotel
dankei hotel rd.
代码从这里开始
use strict;
use warnings;
open (my $fh1, "< $filename1") or die $!;
my @incomin_data1=<$fh1>;
my $array_length1=$#incomin_data1;
my @key; my @value;
for (my $count=0;$count<=$array_length1;$count++)
{($key[$count],$value[$count])=split /,/,$incomin_data1[$count];}
my $key_length=$#key;
open (my $fh2, "< $filename2") or die $!;
my @incomin_data2=<$fh2>;
my $array_length2=$#incomin_data2;
for (my $count2=0;$count2<=$array_length2;$count2++)
{ for (my $count3=0;$count3<=$key_length;$count3++)
{ my $ky=$key[$count3];
my $val=$value[$count3];
if ($incomin_data2[$count2]=~/\s?$val\s?/g)
{ $incomin_data2[$count2]=~s/$val/$ky/; }}}
print "\n\n",@incomin_data2;
我能为您做的最好的就是简单地编写一个解决方案。您自己的代码无法恢复。
use strict;
use warnings;
my ($file1, $file2) = @ARGV;
my %abbrevs;
open my $fh, '<', $file1 or die $!;
while (<$fh>) {
chomp;
my ($phrase, $abbrev) = split /,/;
if ( exists $abbrevs{$abbrev} ) {
die sprintf 'Abbreviation "%s" already assigned to "%s"', $abbrev, $phrase;
}
$abbrevs{$abbrev} = $phrase;
}
my $re = join '|', map quotemeta, sort { length $b <=> length $a } keys %abbrevs;
$re = qr/$re/;
open $fh, '<', $file2 or die $!;
while (<$fh>) {
s/(?<![\w.])($re)(?![\w.])/$abbrevs{}/g;
print;
}
输出
Part.Name.
Gordon house Saint
Gordon Saint house
Gordon Saint house
Gordon Saint house
Gordon Saint house
Hotel palace
Hotel Indiana
nuav Road hotel
dankei hotel Road