Come faccio a confrontare due stringhe in Perl?


178

Come faccio a confrontare due stringhe in Perl?

Sto imparando Perl, ho avuto questa domanda di base cercata qui su StackOverflow e non ho trovato una buona risposta, quindi ho pensato di chiedere.


3
Dovresti prima consultare l'eccellente documentazione fornita con Perl.
Sinan Ünür

5
Potresti voler dare un'occhiata a un libro come Learning Perl (che ho scritto insieme). Non c'erano buone risposte a questa domanda perché è molto semplice. Un tutorial ti aiuterà a raccogliere rapidamente le basi.
brian d foy,

Risposte:


184

Vedi perldoc perlop . Usa lt, gt, eq, ne, e cmpcome appropriato per i confronti di stringhe:

Binary eqrestituisce true se l'argomento left è a stringhe uguale all'argomento right.

Binary nerestituisce true se l'argomento left non è uguale all'argomento right.

Il valore binario cmprestituisce -1, 0 o 1 a seconda che l'argomento sinistro sia stringally minore di, uguale o maggiore dell'argomento destro.

Binary ~~fa una smartmatch tra i suoi argomenti. ...

lt, le, ge, gtE cmputilizzare l'ordine di confronto (ordine) specificato dal locale corrente se un locale uso legacy (ma non use locale ':not_characters') è in vigore. Vedi perllocale . Non mescolarli con Unicode, ma solo con codifiche binarie legacy. I moduli Unicode :: Collate e Unicode :: Collate :: Locale standard offrono soluzioni molto più potenti ai problemi di confronto.


9
Solo un altro, ne per non uguale.
PJT,

4
Potresti voler dire che $ str1 = ~ "$ str2" (non / $ str2 /) controllerà se $ str2 è una sottostringa di $ str1.
Daniel C. Sobral,

@Daniel usa indexper vedere se una stringa è una sottostringa di un'altra.
Sinan Ünür

3
@Daniel: non c'è molta differenza pratica tra = ~ "$ str2" e = ~ / $ str2 / (o solo = ~ $ str2 per quella materia); L'indice è lo strumento giusto, ma se è necessario utilizzare una regex per qualche motivo, fare = ~ / \ Q $ str2 \ E /.
ysth

1
@IliaRostovtsev !=e nenon sono gli stessi, perché !=e nesono definiti come diversi. Quanto è difficile ?! Essendo un operatore di confronto numerico, !=converte entrambi i suoi operandi in numeri perl -E 'say "equal" if not "a" != "b"'.
Sinan Ünür

137
  • cmp Confrontare

    'a' cmp 'b' # -1
    'b' cmp 'a' #  1
    'a' cmp 'a' #  0
  • eq Uguale a

    'a' eq  'b' #  0
    'b' eq  'a' #  0
    'a' eq  'a' #  1
  • ne Non uguale a

    'a' ne  'b' #  1
    'b' ne  'a' #  1
    'a' ne  'a' #  0
  • lt Meno di

    'a' lt  'b' #  1
    'b' lt  'a' #  0
    'a' lt  'a' #  0
  • le Minore o uguale a

    'a' le  'b' #  1
    'b' le  'a' #  0
    'a' le  'a' #  1
  • gt Più grande di

    'a' gt  'b' #  0
    'b' gt  'a' #  1
    'a' gt  'a' #  0
  • ge Maggiore o uguale a

    'a' ge  'b' #  0
    'b' ge  'a' #  1
    'a' ge  'a' #  1

Vedi perldoc perlopper maggiori informazioni.

(Lo sto semplificando un po 'come tutti ma cmprestituisco un valore che è sia una stringa vuota, sia un valore numericamente zero anziché 0, e un valore che è sia la stringa '1'che il valore numerico 1. Questi sono gli stessi valori che ottieni sempre dagli operatori booleani in Perl. Dovresti davvero usare i valori di ritorno solo per operazioni booleane o numeriche, nel qual caso la differenza non ha molta importanza.)


8
Mi piace di più questa risposta. Brevi semplici esempi sono di solito più utili per i neofiti, che solo banali riferimenti a documenti multipagina.
Zon,

@Zon tranne che per i valori di ritorno eq, gt, ltecc non sono corretti ... Tornano vero o falso. cmpRestituisce solo valori numerici specifici.
Sinan Ünür

Perl 6 usa gli stessi operatori tranne che usa leginvece dei cmpquali viene invece usato per confronti generici.
Brad Gilbert,

17

Oltre a Sinan Ünür, elenco completo degli operatori di confronto delle stringhe, Perl 5.10 aggiunge l'operatore di abbinamento intelligente.

L'operatore di abbinamento intelligente confronta due elementi in base al loro tipo. Vedere la tabella seguente per il comportamento 5.10 (credo che questo comportamento stia cambiando leggermente in 5.10.1):

perldoc perlsyn"Abbinamento intelligente in dettaglio" :

Il comportamento di una partita intelligente dipende dal tipo di cosa sono i suoi argomenti. È sempre commutativo, cioè $a ~~ $bsi comporta come $b ~~ $a. Il comportamento è determinato dalla seguente tabella: la prima riga che si applica, in entrambi gli ordini, determina il comportamento della corrispondenza.

  $ a $ b Tipo di codice di corrispondenza implicito della corrispondenza
  ====== ===== ===================== =============
  (sovraccaricare briscola tutto)

  Codice [+] Codice [+] uguaglianza referenziale $ a == $ b   
  Qualsiasi codice [+] verità secondaria scalare $ b -> ($ a)   

  Hash Hash chiavi identiche [ordina chiavi% $ a] ~~ [ordina chiavi% $ b]
  Hash Array hash slice esistenze grep {esiste $ a -> {$ _}} @ $ b
  Hash Regex hash key grep grep / $ b /, chiavi% $ a
  Hash Esiste una voce di hash $ a -> {$ b}

  Array Gli array array sono identici [*]
  Array Regex array grep grep / $ b /, @ $ a
  Array L'array num contiene il numero grep $ _ == $ b, @ $ a 
  Array Qualsiasi array contiene string grep $ _ eq $ b, @ $ a 

  Qualsiasi non definito non definito! Definito $ a
  Qualsiasi modello Regex corrisponde a $ a = ~ / $ b / 
  I risultati di Code () Code () sono uguali $ a -> () eq $ b -> ()
  Qualsiasi codice () verità di chiusura semplice $ b -> () # ignora $ a
  Num numish [!] Uguaglianza numerica $ a == $ b   
  Qualsiasi uguaglianza di stringhe $ aeq $ b   
  Qualsiasi uguaglianza numerica numerica $ a == $ b   

  Qualsiasi Qualsiasi uguaglianza di stringhe $ a eq $ b   

+ - questo deve essere un riferimento di codice il cui prototipo (se presente) non è ""
(i sottotitoli con un "" prototipo sono trattati dalla voce "Code ()" in basso) 
* - ovvero, ogni elemento corrisponde all'elemento dello stesso indice nell'altro
Vettore. Se viene trovato un riferimento circolare, torniamo al referenziale
uguaglianza.   
! - un numero reale o una stringa che assomiglia a un numero

Il "codice di corrispondenza" non rappresenta il vero codice di corrispondenza, ovviamente: è lì solo per spiegare il significato previsto. A differenza di grep, l'operatore di smart match cortocircuita ogni volta che può.

Corrispondenza personalizzata tramite sovraccarico È possibile modificare la modalità di corrispondenza di un oggetto sovraccaricando l' ~~operatore. Questo supera la solita semantica delle partite intelligenti. Vedere overload.


Non sta cambiando leggermente: sta cambiando radicalmente. La corrispondenza intelligente per tutto ciò che non è semplice è seriamente rotta.
brian d foy,

1
Il collegamento dovrebbe probabilmente cambiare poiché i documenti sono cambiati nel frattempo. 5.14.2 attuale
Brad Gilbert

10
print "Matched!\n" if ($str1 eq $str2)

Perl ha operatori di confronto di stringhe e confronto numerico separati per aiutare con la digitazione libera nella lingua. Dovresti leggere perlop per tutti i diversi operatori.


8

L'ovvio sottotesto di questa domanda è:

perché non puoi semplicemente usare ==per controllare se due stringhe sono uguali?

Perl non ha tipi di dati distinti per testo vs. numeri. Entrambi sono rappresentati dal tipo "scalare" . Detto in altro modo, le stringhe sono numeri se li usi come tali .

if ( 4 == "4" ) { print "true"; } else { print "false"; }
true

if ( "4" == "4.0" ) { print "true"; } else { print "false"; }
true

print "3"+4
7

Poiché testo e numeri non sono differenziati in base alla lingua, non possiamo semplicemente sovraccaricare l' ==operatore per fare la cosa giusta per entrambi i casi. Pertanto, Perl fornisce eqdi confrontare i valori come testo:

if ( "4" eq "4.0" ) { print "true"; } else { print "false"; }
false

if ( "4.0" eq "4.0" ) { print "true"; } else { print "false"; }
true

In breve:

  • Perl non ha un tipo di dati esclusivamente per le stringhe di testo
  • usare ==o !=, per confrontare due operandi come numeri
  • usare eqo ne, per confrontare due operandi come testo

Esistono molte altre funzioni e operatori che possono essere utilizzati per confrontare valori scalari, ma conoscere la distinzione tra queste due forme è un primo passo importante.


Java ha lo stesso problema, ma per una ragione diversa (e con implicazioni diverse).
Brent Bradburn,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.