Соответствие определенной строке слов между хешами - PullRequest
0 голосов
/ 28 августа 2018

Я пытаюсь сопоставить этот номер телефона между двумя файлами, и я нашел этот код в потоке стека; Сравнить строки файла для совпадения где-либо во втором файле

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

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Если префикс всегда одинаков в содержании «второго файла»

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

Если это не тот же префикс, поскольку вы упоминаете, что они выглядят как «путь», я предполагаю, что последняя часть этого пути - это фактический номер телефона. Таким образом, решение простое: взять последнюю часть пути. Который также является "самой длинной подстрокой без / в ней привязанной в конце строки $" (при условии, что структура цикла while такая же, как и выше):

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

Или, с другой точки зрения: «Удалите самый длинный префикс с / в конце его из $ line, чем возьмите оставшуюся часть $ line»:

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

И, конечно, если сами номера телефонов можно легко перечислить, например, [0-9]{8} (8 символов из набора [0123456789]), возможно, будет проще просто "взять часть, привязанную к конец строки $, совпадающей с шаблоном телефонного номера ":

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

Если ни один из вышеперечисленных не охватывает ваш сценарий, ну ... я просто плохо догадываюсь:)

0 голосов
/ 29 августа 2018

Если вы хотите отфильтровать число из строки, такой как псевдоним / a / b / c / 0123456789, вы можете просто использовать шаблон как / (\ d +) /, если вы уверены, что в «пути» нет чисел. .

Если вы знаете, что число находится в конце пути, вы можете использовать / (\ d +) $ /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...