Come posso abbinare fine stringa tra i due documenti in Perl?
-
04-10-2019 - |
Domanda
Ho un problema nel fare un programma Perl per la corrispondenza delle parole in due documenti. Diciamo che ci sono documenti A e B.
Per questo voglio eliminare le parole del documento A che non è nel documento B.
Esempio 1 :
A: io mangio la pizza
B: Lei andare al mercato e mangiare la pizza
Risultati: mangiare la pizza
Esempio 2 : A: mangiare la pizza
B: pizza mangiare
risultato: la pizza (L'ordine delle parole è rilevante, in modo da "mangiare" è soppressa.)
Io uso Perl per il sistema e le frasi in ogni documento non è in grandi numeri e quindi penso che non userò SQL
E il programma è un subproram per la classificazione automatica per il saggio Lingua indonesiana (Bahasa)
Grazie, Scusate se la mia domanda è un po 'di confusione. Sono veramente nuovo a 'questo mondo':)
Soluzione
OK, io sono senza accesso al momento quindi questo non è garantito al 100% o anche la compilazione ma dovrebbe fornire abbastanza guida:
Soluzione 1 : (ordine delle parole non importa)
#!/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: $!";
Questo dovrebbe creare un nuovo file "A_new" che contiene solo le parole di A che sono in B.
Questo ha un leggero bug - andrà a sostituire qualsiasi multiplo-spazio bianco nel file A con un singolo spazio, in modo da
word1 word2 word3
diventerà
word1 word2 word3
Può essere fissato, ma sarebbe davvero fastidioso per farlo, quindi non mi sono preoccupato a meno che non sarà assolutamente bisogno, giustamente, che gli spazi bianchi da conservare 100%
Soluzione 2 : (questioni di ordine parola, ma è possibile stampare le parole da file Un fuori, senza riguardo per preservare gli spazi a tutti)
#!/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]";
}
Soluzione 3 (Perché abbiamo bisogno di Perl di nuovo? :))
È possibile farlo banalmente in guscio, senza Perl (o chiamata tramite system () o backticks a genitore script Perl)
comm -12 A B | tr "\012" " "
Per chiamare questo da Perl:
my $new_text = `comm -12 A B | tr "\012" " " `;
Ma vedere il mio ultimo commento perché questo può essere considerato "cattivo Perl" ... almeno se fate questo in un ciclo con molti file che vengono iterato e la cura per le prestazioni.