Comment comparer deux chaînes en Perl?
J'apprends Perl. J'avais posé cette question de base ici sur StackOverflow et je n'ai trouvé aucune bonne réponse; j'ai donc pensé poser la question.
Voir perldoc perlop . Utilisez lt
, gt
, eq
, ne
et cmp
comme approprié pour les comparaisons de chaînes:
Binary
eq
renvoie true si l'argument de gauche est stringwise égal à l'argument de droite.Binary
ne
renvoie true si l'argument gauche est stringwise différent de l'argument right.Binary
cmp
renvoie -1, 0 ou 1 selon que l'argument de gauche est inférieur ou égal à chaîne, ou supérieur à l'argument de droite.Binary
~~
effectue une correspondance intelligente entre ses arguments. ...
lt
,le
,ge
,gt
etcmp
utilisent l'ordre de tri (tri) spécifié par les paramètres régionaux actuels si un paramètre régional existant est utilisé (mais pasuse locale ':not_characters'
) est en vigueur. Voir perllocale . Ne les mélangez pas avec Unicode, mais uniquement avec des encodages binaires hérités. Les modules standard nicode :: Collate et nicode :: Collate :: Locale offrent des solutions bien plus puissantes aux problèmes de classement.
cmp
Comparer
_'a' cmp 'b' # -1
'b' cmp 'a' # 1
'a' cmp 'a' # 0
_
eq
Égal à
_'a' eq 'b' # 0
'b' eq 'a' # 0
'a' eq 'a' # 1
_
ne
Pas égal à
_'a' ne 'b' # 1
'b' ne 'a' # 1
'a' ne 'a' # 0
_
lt
Inférieur à
_'a' lt 'b' # 1
'b' lt 'a' # 0
'a' lt 'a' # 0
_
le
Inférieur ou égal à
_'a' le 'b' # 1
'b' le 'a' # 0
'a' le 'a' # 1
_
gt
Supérieur à
_'a' gt 'b' # 0
'b' gt 'a' # 1
'a' gt 'a' # 0
_
ge
Supérieur ou égal à
_'a' ge 'b' # 0
'b' ge 'a' # 1
'a' ge 'a' # 1
_
Voir perldoc perlop
pour plus d'informations.
(Je simplifie un peu ceci car tous sauf cmp
retournent une valeur qui est à la fois une chaîne vide et une valeur numériquement nulle au lieu de _0
_, et une valeur qui est à la fois la chaîne _'1'
_ et la valeur numérique _1
_. Ce sont les mêmes valeurs que vous obtiendrez toujours des opérateurs booléens en Perl. Vous ne devriez utiliser que les valeurs renvoyées pour les opérations booléennes ou numériques, auquel cas la différence ne correspond pas. t vraiment important.)
En plus de Sinan Ünür liste complète des opérateurs de comparaison de chaînes, Perl 5.10 ajoute l’opérateur de correspondance intelligente.
L'opérateur de correspondance intelligente compare deux éléments en fonction de leur type. Voir le tableau ci-dessous pour le comportement 5.10 (je crois que ce comportement change légèrement en 5.10.1):
perldoc perlsyn
"Correspondance intelligente en détail" :Le comportement d'une correspondance intelligente dépend du type d'objet de ses arguments. Il est toujours commutatif, c'est-à-dire que
$a ~~ $b
se comporte de la même manière que$b ~~ $a
. Le comportement est déterminé par le tableau suivant: la première ligne qui s'applique, dans l'un ou l'autre ordre, détermine le comportement de la correspondance.$ a $ b Type de correspondance Code de correspondance implicite ====== ===== =================== == ============= (la surcharge l'emporte sur tout) Code [+] Code [+] égalité référentielle $ a == $ b N'importe quel code [+] vérité scalaire $ b -> ($ a) Hash Hash Les clés de hachage sont identiques [clés de tri% $ a] ~~ [clés de tri% $ b] Existence de la tranche de hachage du tableau de hachage grep {existe $ a -> {$ _}} @ $ b Clé de hachage Hash Regex grep grep/$ b /, clés% $ a Hash Toute existence d’entrée de hachage existe $ a -> {$ b} Tableau Les tableaux sont identiques [*] Tableau Tableau regex tableau grep grep/$ b /, @ $ a Tableau Le tableau contient le nombre grep $ _ == $ b, @ $ a Tableau Tout tableau contient la chaîne grep $ _eq $ b, @ $ a Tous les indéfinis! $ A Tous les regex pat correspondance de stern $ a = ~/$ b/ Code () Code () les résultats sont égaux à $ a -> () eq $ b -> () N'importe quel code () fermeture simple vérité $ b -> () # ignorant $ a Num numish [!] égalité numérique $ a == $ b Toute égalité de chaîne de caractères $ a eq $ b N'importe quel nombre d'égalité numérique $ a == $ b N'importe quelle chaîne égalité $ a eq $ b + - il doit s'agir d'une référence de code dont le prototype (si présent) est not "" (les subs avec un "" prototype sont traités par l'entrée "Code ()" plus bas) * - c'est-à-dire que chaque élément correspond à l'élément du même index dans l'autre tableau. Si une référence circulaire est trouvée, nous retombons sur l'égalité référentielle . ! - soit un nombre réel, soit une chaîne qui ressemble à un nombreLe "code de correspondance" ne représente pas le code de correspondance réel, bien sûr: il est juste là pour expliquer le sens voulu. Contrairement à grep, l'opérateur de match intelligent court-circuitera chaque fois qu'il le pourra.
Correspondance personnalisée par surcharge Vous pouvez modifier le mode de correspondance d'un objet en surchargeant l'opérateur
~~
. Cela remplace la sémantique habituelle des correspondances intelligentes. Voiroverload
.
print "Matched!\n" if ($str1 eq $str2)
Perl dispose d'opérateurs de comparaison de chaînes et numériques différents pour faciliter la frappe dans la langue. Vous devriez lire perlop pour tous les différents opérateurs.
Le sous-texte évident de cette question est:
pourquoi ne pouvez-vous pas simplement utiliser
==
pour vérifier si deux chaînes sont identiques?
Perl n'a pas de types de données distincts pour le texte par rapport aux nombres. Ils sont tous deux représentés par le type "scalar" . En d'autres termes, les chaînes sont des nombres si vous les utilisez tels quels .
if ( 4 == "4" ) { print "true"; } else { print "false"; }
true
if ( "4" == "4.0" ) { print "true"; } else { print "false"; }
true
print "3"+4
7
Puisque le texte et les nombres ne sont pas différenciés par la langue, nous ne pouvons pas simplement surcharger l'opérateur ==
pour qu'il fasse la bonne chose dans les deux cas. Par conséquent, Perl fournit eq
pour comparer les valeurs sous forme de texte:
if ( "4" eq "4.0" ) { print "true"; } else { print "false"; }
false
if ( "4.0" eq "4.0" ) { print "true"; } else { print "false"; }
true
En bref:
==
ou !=
, pour comparer deux opérandes sous forme de nombreseq
ou ne
, pour comparer deux opérandes en tant que texteIl existe de nombreuses autres fonctions et opérateurs pouvant être utilisés pour comparer des valeurs scalaires, mais connaître la distinction entre ces deux formes est une première étape importante.
Et si vous souhaitez extraire les différences entre les deux chaînes, vous pouvez utiliser String :: Diff .