¿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.
¿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.
Respuestas:
Ver perldoc perlop . Uso lt
, gt
, eq
, ne
, y cmp
según sea apropiado para las comparaciones de cadenas:
El binario
eq
devuelve verdadero si el argumento izquierdo es igual en cadena al argumento derecho.El binario
ne
devuelve verdadero si el argumento izquierdo es en cadena no igual al argumento derecho.Binario
cmp
devuelve -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
,gt
Ycmp
utilizar el orden de clasificación (más o menos) especificado por la localización actual si un local legado uso (pero nouse 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.
index
para ver si una cadena es una subcadena de otra.
!=
y ne
no son lo mismo, porque !=
y ne
se 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"'
.
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 perlop
para más información.
(Estoy simplificando esto un poco, pero cmp
devuelvo 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).
eq
, gt
, lt
etc, no son correctas ... Vuelven verdadero o falso. Solo cmp
devuelve valores numéricos específicos.
leg
lugar de los cmp
que se usan para comparaciones genéricas.
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 ~~ $b
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 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úmeroEl "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. Veroverload
.
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.
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 eq
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 breve:
==
o !=
, para comparar dos operandos como númeroseq
o ne
, para comparar dos operandos como textoHay 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.
Y si desea extraer las diferencias entre las dos cadenas, puede usar String :: Diff .