¿Cómo comparo dos cadenas en Perl?


¿Cómo comparo dos cadenas en Perl?

Estoy aprendiendo Perl, hice que esta pregunta básica la buscara aquí en StackOverflow y no encontré una buena respuesta, así que pensé en preguntar.

Author: Sinan Ünür, 2009-07-24

6 answers

Véase perldoc perlop. Uso lt, gt, eq, ne, y cmp como apropiado para comparaciones de cadenas:

Binary eq devuelve true si el argumento de la izquierda es igual al argumento de la derecha.

Binary ne devuelve true si el argumento de la izquierda no es igual al argumento de la derecha.

Binary cmp devuelve -1, 0 o 1 dependiendo de si el argumento izquierdo es menor, igual o mayor que el derecho argumento.

Binary ~~ hace un smartmatch entre sus argumentos. ...

lt, le, ge, gt y cmp use el orden de intercalación (ordenación) especificado por la configuración regional actual si una configuración regional de uso heredada (pero no use locale ':not_characters') está en vigor. Véase perllocale . No mezcle estos con Unicode, solo con codificaciones binarias heredadas. Los módulos estándar Unicode::Collate y Unicode:: Collate:: Locale ofrecen soluciones mucho más potentes para la intercalación cuestión.

 153
Author: Sinan Ünür,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-01 16:53:37
  • cmp Comparar

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

    'a' eq  'b' #  0
    'b' eq  'a' #  0
    'a' eq  'a' #  1
    
  • ne No-Igual a

    'a' ne  'b' #  1
    'b' ne  'a' #  1
    'a' ne  'a' #  0
    
  • lt Inferior a

    'a' lt  'b' #  1
    'b' lt  'a' #  0
    'a' lt  'a' #  0
    
  • le Menor o igual a

    'a' le  'b' #  1
    'b' le  'a' #  0
    'a' le  'a' #  1
    
  • gt Mayor que

    'a' gt  'b' #  0
    'b' gt  'a' #  1
    'a' gt  'a' #  0
    
  • ge Mayor o igual a

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

Véase perldoc perlop para más información.

(Estoy simplificando esto un poco como todos, pero cmp devuelve un valor que es una cadena vacía, y numéricamente el valor cero en lugar de 0, y un valor que es la cadena '1' y el valor numérico 1. Estos son los mismos valores que siempre obtendrá de los operadores booleanos en Perl. Realmente solo debería usar los valores devueltos para operaciones booleanas o numéricas, en cuyo caso la diferencia realmente no importa. )

 120
Author: Brad Gilbert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-25 14:32:44

En adición a la lista completa de operadores de comparación de cadenas Sinan ÜnÜr, Perl 5.10 agrega el operador smart match.

El operador smart match compara dos elementos según su tipo. Vea la tabla a continuación para el comportamiento 5.10 (creo que este comportamiento está cambiando ligeramente en 5.10.1):

perldoc perlsyn "Coincidencia inteligente en detalle":

El comportamiento de una coincidencia inteligente depende de qué tipo de cosa son sus argumentos. Siempre es conmutativa, es decir, $a ~~ $b se comporta igual que $b ~~ $a . El comportamiento está determinado por la siguiente tabla: la primera fila que se aplica, en cualquier orden, determina el comportamiento del partido.

  $a      $b        Type of Match Implied    Matching Code
  ======  =====     =====================    =============
  (overloading trumps everything)

  Code[+] Code[+]   referential equality     $a == $b   
  Any     Code[+]   scalar sub truth         $b−>($a)   

  Hash    Hash      hash keys identical      [sort keys %$a]~~[sort keys %$b]
  Hash    Array     hash slice existence     grep {exists $a−>{$_}} @$b
  Hash    Regex     hash key grep            grep /$b/, keys %$a
  Hash    Any       hash entry existence     exists $a−>{$b}

  Array   Array     arrays are identical[*]
  Array   Regex     array grep               grep /$b/, @$a
  Array   Num       array contains number    grep $_ == $b, @$a 
  Array   Any       array contains string    grep $_ eq $b, @$a 

  Any     undef     undefined                !defined $a
  Any     Regex     pattern match            $a =~ /$b/ 
  Code()  Code()    results are equal        $a−>() eq $b−>()
  Any     Code()    simple closure truth     $b−>() # ignoring $a
  Num     numish[!] numeric equality         $a == $b   
  Any     Str       string equality          $a eq $b   
  Any     Num       numeric equality         $a == $b   

  Any     Any       string equality          $a eq $b   

+ − this must be a code reference whose prototype (if present) is not ""
(subs with a "" prototype are dealt with by the 'Code()' entry lower down) 
* − that is, each element matches the element of same index in the other
array. If a circular reference is found, we fall back to referential 
equality.   
! − either a real number, or a string that looks like a number

El "código coincidente" no representa el código coincidente real, por supuesto: solo está ahí para explicar el significado pretendido. A diferencia de grep, el operador smart match cortocircuitará siempre que pueda.

Coincidencia personalizada mediante sobrecarga Puede cambiar la forma en que se compara un objeto sobrecargando el ~~ operador. Esto supera a la habitual semántica de partidos inteligentes. Véase overload.

 16
Author: Chas. Owens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-12 20:08:27
print "Matched!\n" if ($str1 eq $str2)

Perl tiene operadores separados de comparación de cadenas y comparación numérica para ayudar con la escritura suelta en el idioma. Debe leer perlop para todos los diferentes operadores.

 9
Author: Matthew Scharley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-24 01:35:10

El subtexto obvio de esta pregunta es:

¿Por qué no puedes simplemente usar == para comprobar si dos cadenas son iguales?

Perl no tiene tipos de datos distintos para texto vs.números. Ambos están representados por el tipo "escalar". Dicho de otra manera, las cadenas son números si las usas como tales.

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

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

print "3"+4
7

Dado que el texto y los números no están diferenciados por el lenguaje, no podemos simplemente sobrecargar el == operador para hacer lo correcto en ambos casos. Por lo tanto, Perl proporciona eq para comparar valores como texto:

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

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

En resumen:

  • Perl no tiene un tipo de datos exclusivamente para cadenas de texto
  • use == o !=, para comparar dos operandos como números
  • use eq o ne, para comparar dos operandos como texto

Hay muchas otras funciones y operadores que se pueden usar para comparar valores escalares, pero conociendo la distinción entre estas dos formas es un primer paso importante.

 5
Author: nobar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:29:56

Y si desea extraer las diferencias entre las dos cadenas, puede usar String::Diff.

 1
Author: Helen Craigman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-14 16:18:09