【问题标题】:Matching certain line of words between hashes匹配哈希之间的某些单词行
【发布时间】:2018-10-11 15:09:03
【问题描述】:

我正在尝试在两个文件之间匹配此电话号码,我在堆栈流中找到了此代码; Compare file lines for match anywhere in second file

    use strict;   #ALWAYS ALWAYS ALWAYS
    use warnings; #ALWAYS ALWAYS ALWAYS

    use autodie;  #Will end the program if files you try to open don't exist

    # Constants are a great way of storing data that is ...uh... constant
    use constant {
        FILE_1    =>  "a1.txt",
        FILE_2    =>  "a2.txt",
    };

my %phone_hash1;
my %phone_hash2;

open my $phone_num1_fh, "<", FILE_1;

while ( my $phone_num = <$phone_num1_fh> ) {
    chomp $phone_num;
    $phone_hash1{ $phone_num } = 1;
}
close $phone_num1_fh;

open my $phone_num2_fh, "<", FILE_2;

while ( my $phone_num = <$phone_num2_fh> ) {
    chomp $phone_num;
    $phone_hash2{ $phone_num } = 1;
}
close $phone_num2_fh;

my %in_common;

for my $phone ( keys %phone_hash1 ) {
    if ( $phone_hash2{$phone} ) { 
       $in_common{$phone} = 1;    #Phone numbers in common between the two lists
    }
}
for my $phone ( sort keys %phone_hash1 ) {
    if ( not $in_common{$phone} ) {
         print "Phone number $phone is only in the first file\n";
    }
}

for my $phone ( sort keys %phone_hash2 ) {
    if ( not $in_common{$phone} ) {
        print "Phone number $phone is only in " . FILE_2 . "\n";
    }
}

for my $phone ( sort keys %in_common ) {
    print "Phone number $phone is in both files\n";
}

问题是; 在我的第一个文件中,我需要过滤掉电话号码, 所以,我试着做这个;

 if ($s1 =~ m/(.*)\s+(.*)\s+(.*)\s+/) 
        {
        my $phone_num=($1."/".$2);
        chomp $phone_num;
        $phone_hash1{ $phone_num } = 1;
        }

我的第二个文件电话号码前面有一个路径 比如别名/a/b/c/0123456789

我不知道如何将这个数字过滤到哈希中,或者过滤掉我不想要的东西,以便我可以在两个文件之间比较这两个数字。

($phone_hash2{ $phone_num }  =~ /.*$str/)

【问题讨论】:

  • 我们可以在这里使用一些示例数据,以及您要过滤的内容的示例。

标签: perl


【解决方案1】:

如果前缀在“第二个文件”的内容中总是相同的

alias/a/b/c/${phone_number_1}
alias/a/b/c/${phone_number_2}
alias/a/b/c/${phone_number_3}

然后可以通过 substr 删除前缀:

my $offset = length("alias/a/b/c/");
while(my $line = <$fh_file>) { 
    chomp($line);
    $line = substr($line, $offset);
}

如果不是同一个前缀,因为您提到它们看起来像“路径”,我将假设该路径的最后一部分是实际的电话号码。所以解决方案很简单:走路径的最后一部分。这也是“在 $line 末尾没有任何 / 的最长子字符串”(假设与上述相同的 while 循环结构):

my ($phone) = $line =~ m{([^/]+)\z};

或者,从不同的角度来看:“从 $line 中删除末尾带有 / 的最长前缀,而不是取出 $line 的其余部分”:

my $phone = $line =~ s{\A.+/}{}r;

当然,如果电话号码本身可以用简单的模式枚举,例如,[0-9]{8}[0123456789] 集中的 8 个字符),也许更直接地“取锚定在$line 的结尾匹配电话号码模式”:

my ($phone) = $line =~ m{([0-9]{8})\z};

如果以上都没有涵盖您的情况,那么......我只是不擅长猜测:)

【讨论】:

    【解决方案2】:

    如果您想从像 alias/a/b/c/0123456789 这样的字符串中过滤出数字,如果您确定“路径”中没有数字,则可以使用 /(\d+)/ 之类的模式.

    如果你知道数字在路径的末尾,你可以使用 /(\d+)$/

    【讨论】:

    • 谢谢!使用 perl 比 C 编程更容易。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多