【问题标题】:Exact string matching and replacement of a file using PERL script使用Perl脚本匹配和替换文件的确切字符串
【发布时间】:2013-10-28 18:33:35
【问题描述】:

我有两个如下文件。

  1. 地址文件[查找文件]
POST OFFICE,PO
SUITE ACCESS ROOM, SAR
SUITE,STE
STREET,ST
NEW YORK,NY
POST,PST
LONG LINE STREET,LLS
  1. 主文件[需要查找和替换确切字符串的地方]
ARIJIT, 192 POST OFFICE, SUITE
CHANDA, 13 HP STREET, NY
RAM, POSTING POST, LONG LINE STREET
ROY, POST 3009, SUITE ACCESS ROOM

预期输出:

ARIJIT, 192 PO, STE
CHANDA, 13 HP ST, NEW YORK
RAM, POSTING PST, LLS
ROY, PST 3009, SAR

我正在使用下面的代码,但仍然无法获得任何成功。我是 PERL 的新手。该代码适用于单个单词,但不适用于多个单词。

#!/usr/bin/perl
use warnings;
use strict;
open( my $out_fh, ">", "output.txt" ) || die "Can't open the output file for writing: $!";

open( my $address_fh, "<", "Address.txt" ) || die "Can't open the address file: $!";
my %lookup = map { chomp; split( /,/, $_, 2 ) } <$address_fh>;

open( my $file_fh, "<", $ARGV[0] ) || die "Can't open the file.txt file: $!";
while (<$file_fh>) {
    my @line = split;
    for my $char ( @line ) {
        ( exists $lookup{$char} ) ? print $out_fh "$lookup{$char} " : print $out_fh "$char ";
    }
    print $out_fh "\n";
}

【问题讨论】:

    标签: string algorithm perl replace


    【解决方案1】:

    您的问题出在my @line = split;,它将一行分成单词。由于您的某些替换包含多个单词,因此您不能这样做。

    相反,您应该构建一个匹配所有键的正则表达式,例如:

    my $keywords = join '|', map quotemeta, sort { length($b) <=> length($a) } keys %lookup;
    my $keywords_rx = qr/\b$keywords\b/;
    

    \b 断言在字边界处匹配。我们还必须对键进行排序,以便在较短的匹配之前尝试更长的替代方案。否则,SUITE ACCESS ROOM 可能永远无法匹配。

    然后在s/($keywords_rx)/$lookup{$1}/g 之类的行上执行替换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多