ho il mio codice come questo:Confrontando più stringhe in Perl
if ($var eq "str1" || $var eq "str2" || $var eq "str3")
{
...
}
C'è comunque di ottimizzare questo. voglio qualcosa di simile:
if ($var eq ["str1" || "str2" || "str3"]) {...}
ho il mio codice come questo:Confrontando più stringhe in Perl
if ($var eq "str1" || $var eq "str2" || $var eq "str3")
{
...
}
C'è comunque di ottimizzare questo. voglio qualcosa di simile:
if ($var eq ["str1" || "str2" || "str3"]) {...}
A seconda del contenuto delle stringhe, una regex è molto conveniente:
if ($var =~ /^(str1|str2|str3)$/) { … }
In mancanza di questo, è possibile grep su un elenco:
if (grep { $var eq $_ } qw{str1 str2 str3}) { … }
grazie mille .. La prima espressione ha funzionato ma con le parentesi rimosse: if ($ var = ~/^ str1 | str2 | str3 $ /) – sundar
@ user988967, No, non lo è. Senza i paren, abbinerà 'str1A',' Astr2A' e 'Astr3'. – ikegami
@ikegami, sì, hai ragione. grazie .. Un'altra query. Sto usando "use strict" nella parte superiore del mio codice. quindi mi consigli di usare "?:" – sundar
In Perl 5.10 o successivo:
if ($var ~~ [qw(str1 str2 str3)]) { ...}
L'operatore ~~
fa uno smart match tra i suoi argomenti.
+1; Non avevo idea che questo operatore esista. –
@MarceloCantos: *** "L'operatore smartmatch è sperimentale e il suo comportamento è soggetto a modifiche." *** Vi consiglio di evitarlo – Borodin
@Borodin: In genere evito Perl, ma +1 per l'heads-up comunque. –
Usa List::MoreUtils qw{any}
use List::MoreUtils qw{any};
if (any { $var eq $_ } 'str1', 'str2', 'str3') {
...
}
Questo potrebbe essere più veloce rispetto all'utilizzo di grep
perchè List::MoreUtils::any
termina presto quando trova una corrispondenza, mentre grep
potrebbe costruire un elenco completo delle partite. Dico "potrebbe" perché Perl potrebbe idealmente ottimizzare if (grep ...
. Potrebbe non farlo. Ma List::MoreUtils::any
termina presto ed è più descrittivo rispetto all'idioma if (grep ...
.
Fare un hash che ha le chiavi di tutte le stringhe che si desidera abbinare
my %matcher;
@matcher{qw{str1 str2 str3}} =();
if (exists $matcher{$var}) {
...
}
Questo ha lo svantaggio di un tempo di set-up e il costo della memoria utilizzata per l'hash, ma il vantaggio è che il tempo di corrispondenza è più simile a O (log N). Quindi, se hai un sacco di valori diversi di $var
che vuoi testare, potrebbe essere più veloce nel complesso.
Fai un espressione regolare che corrisponde a tutte le vostre corde
if ($var =~ m/^str[123]$/so) {
...
}
OK, quindi questo va bene se le corde sono letteralmente qw{str1 str2 str3}
, ma cosa succede se si tratta di una lista di stringhe arbitrarie?
È possibile utilizzare Regexp::Assemble per fondere insieme un elenco di espressioni regolari in una singola espressione regolare ottimizzata.
[Regexp :: Assemble] (http://p3rl.org/Regexp::ssssemble) non è necessario sui più recenti Perls, poiché le espressioni regolari ora hanno [ottimizzazione Trie] (http://perldoc.perl.org/perl5100delta.html # Trie-ottimizzazione-of-letterale-string-alternanze). –
Sono semi-scherzando, ma questo lo farà:
use Quantum::Superpositions;
if ($x == any($a, $b, $c)) { ... }
Vedi anche questo Perl Monks thread
Per una lista di stringhe fisse, convertire la vostra lista per un hash. Questo è particolarmente utile se stai andando a controllare il tuo elenco più volte, e se la tua lista diventa più grande.
%on_my_list = map {; $_ => 1 } 'str1', 'str2', 'str3', ...;
if ($on_my_list{$var}) { ... }
Se "ottimizza" intendi "fallo andare più veloce", la prima versione è ottimale (se ordini le stringhe in modo che il più probabile sia davanti). – Mat