Comment comparer deux chaînes en Perl?
J'apprends Perl, j'avais cette question de base recherchée ici sur StackOverflow et je n'ai trouvé aucune bonne réponse, alors j'ai pensé que je demanderais.
Comment comparer deux chaînes en Perl?
J'apprends Perl, j'avais cette question de base recherchée ici sur StackOverflow et je n'ai trouvé aucune bonne réponse, alors j'ai pensé que je demanderais.
Réponses:
Voir perldoc perlop . Utilisez lt
, gt
, eq
, ne
et cmp
le cas échéant pour les comparaisons de chaînes:
Binary
eq
renvoie true si l'argument de gauche est égal dans le sens de la chaîne à l'argument de droite.Binaire
ne
renvoie true si l'argument de gauche n'est pas égal à l'argument de droite dans le sens d'une chaîne.Binary
cmp
renvoie -1, 0 ou 1 selon que l'argument de gauche est inférieur, égal ou supérieur à l'argument de droite dans le sens de la chaîne.Binary
~~
effectue un smartmatch entre ses arguments. ...
lt
,le
,ge
,gt
Etcmp
utiliser le tri (collation) ordre spécifié par les paramètres régionaux en cours si un lieu d'utilisation de l' héritage (mais pasuse locale ':not_characters'
) est en vigueur. Voir perllocale . Ne les mélangez pas avec Unicode, uniquement avec des encodages binaires hérités. Les modules standard Unicode :: Collate et Unicode :: Collate :: Locale offrent des solutions beaucoup plus puissantes aux problèmes de classement.
index
pour voir si une chaîne est une sous-chaîne d'une autre.
!=
et ne
ne sont pas les mêmes, car !=
et ne
sont définis comme étant différents. Est-ce difficile?! Étant un opérateur de comparaison numérique, !=
convertit ses deux opérandes en nombres perl -E 'say "equal" if not "a" != "b"'
.
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
Moins que
'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
Plus grand que
'a' gt 'b' # 0
'b' gt 'a' # 1
'a' gt 'a' # 0
ge
Plus grand 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 cela car tout sauf cmp
retourne une valeur qui est à la fois une chaîne vide et une valeur numérique zéro 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 toujours obtenir des opérateurs booléens en Perl. Vous ne devriez vraiment utiliser les valeurs de retour que pour les opérations booléennes ou numériques, auquel cas la différence n'a pas vraiment d'importance.)
eq
, gt
, lt
etc ne sont pas correctes ... Ils renvoient vrai ou faux. Renvoie uniquement cmp
des valeurs numériques spécifiques.
leg
place cmp
ce qui est utilisé pour les comparaisons génériques à la place.
En plus de la liste complète des opérateurs de comparaison de chaînes de Sinan Ünür, 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 pense que ce comportement change légèrement dans 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 qu'il
$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 correspondance.
$ a $ b Type de correspondance Code de correspondance implicite ====== ===== ===================== ============= (la surcharge l'emporte sur tout) Code [+] Code [+] égalité référentielle $ a == $ b Tout code [+] sous-vérité scalaire $ b -> ($ a) Hash Hash Clés de hachage identiques [clés de tri% $ a] ~~ [clés de tri% $ b] Hash Array existence d'une tranche 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} Les tableaux Array Array sont identiques [*] Tableau Regex tableau grep grep / $ b /, @ $ a Le tableau Array Num contient le nombre grep $ _ == $ b, @ $ a Tableau Tout tableau contient la chaîne grep $ _ eq $ b, @ $ a Tout undef undefined! Defined $ a Tout modèle Regex correspond à $ a = ~ / $ b / Code () Les résultats de Code () sont égaux $ a -> () eq $ b -> () Toute vérité de fermeture simple Code () $ b -> () # ignorant $ a Num numish [!] Égalité numérique $ a == $ b Toute égalité de chaîne Str $ a eq $ b Toute égalité numérique numérique $ a == $ b Any Toute égalité de chaîne $ a eq $ b + - il doit s'agir d'une référence de code dont le prototype (s'il est présent) n'est pas "" (les sous-marins 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, on retombe au référentiel égalité. ! - soit un nombre réel, soit une chaîne qui ressemble à un nombreLe "code correspondant" ne représente pas le vrai code correspondant, bien sûr: il est juste là pour expliquer la signification voulue. Contrairement à grep, l'opérateur de correspondance intelligente court-circuitera chaque fois qu'il le peut.
Correspondance personnalisée via la surcharge Vous pouvez modifier la manière dont un objet est mis en correspondance en surchargeant l'
~~
opérateur. Cela l'emporte sur la sémantique habituelle des correspondances intelligentes. Voiroverload
.
print "Matched!\n" if ($str1 eq $str2)
Perl a des opérateurs de comparaison de chaînes et de comparaison numériques séparés pour faciliter la saisie lâche dans le langage. 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 et les nombres. Ils sont tous deux représentés par le type "scalaire" . En d'autres termes, les chaînes sont des nombres si vous les utilisez comme tels .
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 ce qu'il faut dans les deux cas. Par conséquent, Perl propose eq
de 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 sous forme de 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 .