¿Cómo comparo dos cadenas en Perl?

178

¿Cómo comparo dos cadenas en Perl?

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

PJT
fuente
3
Primero debe consultar la excelente documentación que viene con Perl.
Sinan Ünür
55
Es posible que desee consultar un libro como Learning Perl (del cual soy coautor). No hubo buenas respuestas a esta pregunta porque es muy básica. Un tutorial te ayudará a aprender lo básico rápidamente.
brian d foy

Respuestas:

184

Ver perldoc perlop . Uso lt, gt, eq, ne, y cmpsegún sea apropiado para las comparaciones de cadenas:

El binario eqdevuelve verdadero si el argumento izquierdo es igual en cadena al argumento derecho.

El binario nedevuelve verdadero si el argumento izquierdo es en cadena no igual al argumento derecho.

Binario cmpdevuelve -1, 0 o 1 dependiendo de si el argumento izquierdo es en cadena menor que, igual o mayor que el argumento derecho.

Binary ~~hace una comparación inteligente entre sus argumentos. ...

lt, le, ge, gtY cmputilizar el orden de clasificación (más o menos) especificado por la localización actual si un local legado uso (pero no use locale ':not_characters') está en vigor. Ver 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 problemas de intercalación.

Sinan Ünür
fuente
9
Solo uno más, ne para no igual.
PJT el
44
Es posible que desee mencionar que $ str1 = ~ "$ str2" (no / $ str2 /) verificará si $ str2 es una subcadena de $ str1.
Daniel C. Sobral
@Daniel usa indexpara ver si una cadena es una subcadena de otra.
Sinan Ünür
3
@Daniel: no hay mucha diferencia práctica entre = ~ "$ str2" y = ~ / $ str2 / (o simplemente = ~ $ str2 para el caso); index es la herramienta correcta, pero si necesita usar una expresión regular por alguna razón, haga = ~ / \ Q $ str2 \ E /.
Ysth
1
@IliaRostovtsev !=y neno son lo mismo, porque !=y nese definen como diferentes. ¿Qué tan difícil es eso? Al ser un operador de comparación numérico, !=convierte sus dos operandos en números perl -E 'say "equal" if not "a" != "b"'.
Sinan Ünür
137
  • 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 Menos que

    'a' lt  'b' #  1
    'b' lt  'a' #  0
    'a' lt  'a' #  0
    
  • le Menos que o igual a

    'a' le  'b' #  1
    'b' le  'a' #  0
    'a' le  'a' #  1
    
  • gt Mas grande que

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

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

Ver perldoc perloppara más información.

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

Brad Gilbert
fuente
8
Me gusta más esta respuesta. Los ejemplos breves y simples suelen ser más útiles para los novatos, que solo la referencia banal de documentos de varias páginas.
Zon
@Zon excepto que los valores de retorno de eq, gt, ltetc, no son correctas ... Vuelven verdadero o falso. Solo cmpdevuelve valores numéricos específicos.
Sinan Ünür
Perl 6 usa los mismos operadores, excepto que usa en leglugar de los cmpque se usan para comparaciones genéricas.
Brad Gilbert
17

Además de la lista completa de operadores de comparación de cadenas de Sinan Ünür, Perl 5.10 agrega el operador de coincidencia inteligente.

El operador de comparación inteligente compara dos elementos según su tipo. Consulte el cuadro a continuación para ver el comportamiento 5.10 (creo que este comportamiento está cambiando ligeramente en 5.10.1):

perldoc perlsyn"Emparejamiento inteligente en detalle" :

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

  $ a $ b Tipo de coincidencia Código de coincidencia implícito
  ====== ===== ===================== =============
  (la sobrecarga triunfa sobre todo)

  Código [+] Código [+] igualdad referencial $ a == $ b   
  Cualquier Código [+] verdad sub escalar $ b -> ($ a)   

  Hash Hash claves hash idénticas [ordenar claves% $ a] ~~ [ordenar claves% $ b]
  Hash Array hash slice existencia grep {existe $ a -> {$ _}} @ $ b
  Hash Regex hash key grep grep / $ b /, keys% $ a
  Hash Existe cualquier entrada de hash $ a -> {$ b}

  Matriz Las matrices de matrices son idénticas [*]
  Array Regex array grep grep / $ b /, @ $ a
  La matriz Num de matriz contiene el número grep $ _ == $ b, @ $ a 
  Matriz Cualquier matriz contiene cadena grep $ _ eq $ b, @ $ a 

  Cualquier undef indefinido! Definido $ a
  Cualquier patrón de expresión regular coincide con $ a = ~ / $ b / 
  Los resultados de Code () Code () son iguales $ a -> () eq $ b -> ()
  Cualquier Código () verdad de cierre simple $ b -> () # ignorando $ a
  Num numish [!] Igualdad numérica $ a == $ b   
  Cualquier cadena Str igualdad $ a eq $ b   
  Cualquier igualdad numérica numérica $ a == $ b   

  Cualquiera Cualquier igualdad de cadena $ a eq $ b   

+ - debe ser una referencia de código cuyo prototipo (si está presente) no es ""
(los subs con un "" prototipo se tratan con la entrada 'Código ()' más abajo) 
* - es decir, cada elemento coincide con el elemento del mismo índice en el otro
formación. Si se encuentra una referencia circular, volvemos a referencial
igualdad.   
! - ya sea un número real o una cadena que se parece a un número

El "código de coincidencia" no representa el código de coincidencia real, por supuesto: solo está ahí para explicar el significado deseado. A diferencia de grep, el operador de partido inteligente cortocircuitará siempre que pueda.

Coincidencia personalizada mediante sobrecarga Puede cambiar la forma en que se hace coincidir un objeto sobrecargando el ~~operador. Esto supera la habitual semántica de partido inteligente. Ver overload.

Chas Owens
fuente
No está cambiando ligeramente: está cambiando radicalmente. La coincidencia inteligente para cualquier cosa no simple está seriamente rota.
brian d foy
1
El enlace debería cambiar probablemente ya que los documentos han cambiado mientras tanto. 5.14.2 actual
Brad Gilbert
10
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. Debería leer perlop para todos los diferentes operadores.

Matthew Scharley
fuente
8

El subtexto obvio de esta pregunta es:

¿por qué no puedes usar ==para verificar si dos cadenas son iguales?

Perl no tiene tipos de datos distintos para texto versus 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 idioma, no podemos simplemente sobrecargar al ==operador para que haga lo correcto en ambos casos. Por lo tanto, Perl proporciona eqcomparar 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 breve:

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

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

Brent Bradburn
fuente
Java tiene el mismo problema, pero por una razón diferente (y con diferentes implicaciones).
Brent Bradburn