web-dev-qa-db-fra.com

Comment comparer deux chaînes en Perl?

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.

167
PJT

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 et cmp 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 pas use 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.

171
Sinan Ünür
  • 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.)

132
Brad Gilbert

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 nombre 

Le "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. Voir overload .

17
Chas. Owens
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.

10
Matthew Scharley

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:

  • Perl n'a pas de type de données exclusivement pour les chaînes de texte
  • utilisez == ou !=, pour comparer deux opérandes sous forme de nombres
  • utilisez eq ou ne, pour comparer deux opérandes en tant que texte

Il 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.

7
nobar

Et si vous souhaitez extraire les différences entre les deux chaînes, vous pouvez utiliser String :: Diff .

1
Helen Craigman