Wie vergleiche ich zwei Strings in Perl?

Wie vergleiche ich zwei Strings in Perl?

Ich lerne Perl, ich hatte diese grundlegende Frage hier auf StackOverflow und fand keine gute Antwort, also dachte ich, ich würde fragen.

Siehe perldoc perlop . Verwenden Sie lt , gt , eq , ne und cmp wie für String-Vergleiche geeignet:

Binary eq gibt true zurück, wenn das linke Argument stringweise gleich dem rechten Argument ist.

Binärne gibt true zurück, wenn das linke Argument stringweise nicht dem rechten Argument entspricht.

Binäre cmp gibt -1, 0 oder 1 zurück, abhängig davon, ob das linke Argument stringweise kleiner als, gleich oder größer als das rechte Argument ist.

Binary ~~ macht ein Smartmatch zwischen seinen Argumenten. …

lt , le , ge , gt und cmp verwenden die Sortierreihenfolge (Sortierung), die vom aktuellen Gebietsschema angegeben wird, wenn ein use locale ':not_characters' Gebietsschema verwendet wird (aber nicht use locale ':not_characters' ). Siehe perlokal . Mischen Sie diese nicht mit Unicode, nur mit älteren Binärcodierungen. Die standardmäßigen Unicode :: Collate- und Unicode :: Collate :: Locale- Module bieten viel leistungsfähigere Lösungen für Kollationsprobleme.

  • cmp Vergleichen

     'a' cmp 'b' # -1 'b' cmp 'a' # 1 'a' cmp 'a' # 0 
  • gleich

     'a' eq 'b' # 0 'b' eq 'a' # 0 'a' eq 'a' # 1 
  • ne Nicht gleich

     'a' ne 'b' # 1 'b' ne 'a' # 1 'a' ne 'a' # 0 
  • lt weniger als

     'a' lt 'b' # 1 'b' lt 'a' # 0 'a' lt 'a' # 0 
  • le Kleiner als oder gleich

     'a' le 'b' # 1 'b' le 'a' # 0 'a' le 'a' # 1 
  • gt Größer als

     'a' gt 'b' # 0 'b' gt 'a' # 1 'a' gt 'a' # 0 
  • ge Größer als oder gleich

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

Weitere Informationen finden Sie unter perldoc perlop .

(Ich vereinfache dies ein wenig, da alle außer cmp einen Wert zurückgeben, der sowohl eine leere Zeichenfolge als auch einen numerischen Nullwert anstelle von 0 und einen Wert darstellt, der sowohl die Zeichenfolge '1' als auch den numerischen Wert 1 sind die gleichen Werte, die Sie immer von booleschen Operatoren in Perl erhalten. Sie sollten die Rückgabewerte wirklich nur für boolesche oder numerische Operationen verwenden, in welchem ​​Fall der Unterschied keine Rolle spielt.)

Zusätzlich zu Sinan Ünür fügt Perl 5.10 den Smart-Match-Operator hinzu.

Der Smart-Match-Operator vergleicht zwei Elemente basierend auf ihrem Typ. Siehe das Diagramm unten für das 5.10-Verhalten (ich glaube, dass sich dieses Verhalten in 5.10.1 leicht ändert):

perldoc perlsyn “Intelligentes Matching im Detail” :

Das Verhalten einer intelligenten Übereinstimmung hängt davon ab, um welche Art von Argumente es sich handelt. Es ist immer kommutativ, dh $a ~~ $b verhält sich genauso wie $b ~~ $a . Das Verhalten wird durch die folgende Tabelle bestimmt: Die erste Zeile, die in beliebiger Reihenfolge gilt, bestimmt das Übereinstimmungsverhalten.

   $ a $ b Art der Übereinstimmung Implizierter Matching-Code
   ====== ==============================================
   (Überladung trumpft alles auf)

   Code [+] Code [+] referenzielle Gleichheit $ a == $ b   
   Jeder Code [+] skalare Subwahrheit $ b -> ($ a)   

   Hash Hash Hash Keys identisch [Sortierschlüssel% $ a] ~~ [Sortierschlüssel% $ b]
   Hash-Array Hash-Slice-Existenz grep {existiert $ a -> {$ _}} @ $ b
   Hash Regex-Hash-Schlüssel grep grep / $ b /, Schlüssel% $ a
   Hash Ein vorhandener Hash-Eintrag existiert $ a -> {$ b}

   Array Array Arrays sind identisch [*]
   Array-Regex-Array grep grep / $ b /, @ $ a
   Array Num Array enthält die Nummer grep $ _ == $ b, @ $ a 
   Array Jedes Array enthält die Zeichenfolge grep $ _ eq $ b, @ $ a 

   Irgendein undefiniertes undefiniertes! Definiertes $ a
   Jedes Regex-Muster entspricht $ a = ~ / $ b / 
   Code () Code () Ergebnisse sind gleich $ a -> () eq $ b -> ()
   Jeder Code () einfache Schließung Wahrheit $ b -> () # Ignorieren $ a
   Num numische [!] Numerische Gleichheit $ a == $ b   
   Jede Str String Gleichheit $ a eq $ b   
   Eine beliebige numerische Gleichheit $ a == $ b   

   Beliebige Gleichheit Gleichheit $ a eq $ b   

 + - Dies muss eine Codereferenz sein, deren Prototyp (falls vorhanden) nicht "" ist.
 (Subs mit einem "" Prototyp werden durch den 'Code ()' Eintrag weiter unten behandelt) 
 * - jedes Element entspricht dem Element des gleichen Index in dem anderen
 Array.  Wenn eine zirkuläre Referenz gefunden wird, greifen wir auf referenziell zurück 
 Gleichberechtigung.   
 !  - entweder eine reelle Zahl oder eine Zeichenfolge, die wie eine Zahl aussieht

Der “passende Code” repräsentiert natürlich nicht den echten passenden Code: Er ist nur dazu da, die beabsichtigte Bedeutung zu erklären. Im Gegensatz zu grep wird der Smart-Match-Operator immer dann kurzschließen, wenn es möglich ist.

Benutzerdefinierter Abgleich durch Überladen Sie können die Art ändern, in der ein Objekt abgeglichen wird, indem Sie den Operator ~~ überladen. Dies übertrumpft die übliche Smart-Match-Semantik. Siehe overload .

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

Perl verfügt über separate Zeichenfolgenvergleichs- und numerische Vergleichsoperatoren, die bei der losen Typisierung in der Sprache helfen. Sie sollten Perlop für alle verschiedenen Operatoren lesen.

Der offensichtliche Subtext dieser Frage ist:

Warum kannst du nicht einfach == benutzen, um zu prüfen, ob zwei Strings gleich sind?

Perl hat keine unterschiedlichen Datentypen für Text und Zahlen. Sie werden beide vom Typ “Skalar” dargestellt . Anders gesagt, Strings sind Zahlen, wenn Sie sie als solche verwenden .

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

Da Text und Zahlen nicht von der Sprache unterschieden werden, können wir den Operator == nicht einfach überladen, um in beiden Fällen das Richtige zu tun. Daher bietet Perl die Möglichkeit, Werte als Text zu vergleichen:

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

Zusamenfassend:

  • Perl hat keinen Datentyp ausschließlich für Textstrings
  • Verwenden Sie == oder != , um zwei Operanden als Zahlen zu vergleichen
  • Verwenden Sie eq oder ne , um zwei Operanden als Text zu vergleichen

Es gibt viele andere functionen und Operatoren, die zum Vergleichen von Skalarwerten verwendet werden können, aber die Unterscheidung zwischen diesen beiden Formen ist ein wichtiger erster Schritt.

Und wenn Sie die Unterschiede zwischen den beiden Strings extrahieren möchten, können Sie String :: Diff verwenden .