Как я могу соответствовать строку порядка между двумя документами в Perl?
-
04-10-2019 - |
Вопрос
У меня проблема в создании программы Perl для сопоставления слов в двух документах. Допустим, есть документы A и B.
Поэтому я хочу удалить слова в документе A, которые не в документе B.
Пример 1.:
A: Я ем пиццу
B: она ходит на рынок и ешь пиццу
Результат: Ешьте пиццу
Пример 2.: A: есть пиццу
B: пицца есть
Результат: пицца (порядок слов актуален, поэтому «есть» удалено.)
Я использую Perl для системы, и предложения в каждом документе не в большом количестве, поэтому я думаю, что не буду использовать SQL
И программа представляет собой подпрограмм для автоматического сортировки эссе для индонезийского языка (BAHASA)
Спасибо, извините, если мой вопрос немного запутается. Я действительно новый «этот мир» :)
Решение
Хорошо, я без доступа в данный момент, так что это не гарантированно составлять 100% или даже компилировать, но должно обеспечить достаточно рекомендаций:
Решение 1.: (слово порядок не имеет значения)
#!/usr/bin/perl -w
use strict;
use File::Slurp;
my @B_lines = File::Slurp::read_file("B") || die "Error reading B: $!";
my %B_words = ();
foreach my $line (@B_lines) {
map { $B_words{$_} = 1 } split(/\s+/, $line);
}
my @A_lines = File::Slurp::read_file("A") || die "Error reading A: $!";
my @new_lines = ();
foreach my $line (@A_lines) {
my @B_words_only = grep { $B_words{$_} } split(/\s+/, $line);
push @new_lines, join(" ", @B_words_only) . "\n";
}
File::Slurp::write_file("A_new", @new_lines) || die "Error writing A_new: $!";
Это должно создать новый файл «a_new», который содержит только слова в B.
Это имеет небольшую ошибку - это заменит любое множество пробелов в файл с одним пространством, поэтому
word1 word2 word3
станет
word1 word2 word3
Это может быть исправлено, но было бы действительно раздражать, чтобы сделать это, поэтому я не беспокоился, если вы не будете полностью требовать, чтобы пробел был консервирован на 100% правильно
Решение 2.: (Слово порядок вата, но вы можете печатать слова из файла AUT без пожеланий для сохранения пробела вообще)
#!/usr/bin/perl -w
use strict;
use File::Slurp;
my @A_words = split(/\s+/gs, File::Slurp::read_file("A") || die "Error reading A:$!");
my @B_words = split(/\s+/gs, File::Slurp::read_file("B") || die "Error reading B:$!");
my $B_counter = 0;
for (my $A_counter = 0; $A_counter < scalar(@A_words); ++$A_counter) {
while ($B_counter < scalar(@B_words)
&& $B_words[$B_counter] ne $A_words[$A_counter]) {++$B_counter;}
last if $B_counter == scalar(@B_words);
print "$A_words[$A_counter]";
}
Решение 3. (Зачем нам снова нужен Perl? :))
Вы можете сделать это тривиально в оболочке без Perl (или через System () Call или Backticks в Perl Perl)
comm -12 A B | tr "\012" " "
Чтобы назвать это из Perl:
my $new_text = `comm -12 A B | tr "\012" " " `;
Но увидите мой последний комментарий, почему это может считаться «плохим Perl» ... по крайней мере, если вы делаете это в цикле с очень многими файлами и уход за производительностью.