CONTENIDO

  • NOMBRE
  • DESCRIPCIÓN
    • Precedencia y asociatividad del operador
    • Términos y operadores de lista (hacia la izquierda)
    • El operador de flecha
    • Auto-incremento y auto-decremento
    • Exponenciación
    • Operadores unarios simbólicos
    • Operadores vinculantes
    • Operadores multiplicativos
    • Operadores aditivos
    • Operadores de turnos
    • Operadores unarios nombrados
    • Operadores relacionales
    • Operadores de igualdad
    • Operador de instancia de clase
    • Operador de Smartmatch
      • Coincidencia inteligente de objetos
    • Bit a bit y
    • O bit a bit y O exclusivo
    • Lógico estilo C y
    • O lógico de estilo C
    • Definido lógico-Or
    • Operadores de rango
    • Operador condicional
    • Operadores de Asignación
    • Operador de coma
    • Operadores de lista (hacia la derecha)
    • Lógico no
    • Lógico y
    • O lógico y exclusivo O
    • C Operadores que faltan en Perl
    • Operadores de cotizaciones y cotizaciones
    • Operadores tipo cotización Regexp
    • Operadores similares a cotizaciones
    • Detalles sangrientos del análisis sintáctico de construcciones entre comillas
    • Operadores de E / S
    • Plegado constante
    • Sin operaciones
    • Operadores de cadena bit a bit
    • Aritmética de enteros
    • Aritmética de coma flotante
    • Números más grandes

NOMBRE

perlop – Operadores de Perl y precedencia

DESCRIPCIÓN

En Perl, el operador determina qué operación se realiza, independientemente del tipo de operandos. Por ejemplo $x + $y es siempre una suma numérica, y si $x o $y no contienen números, se intenta convertirlos primero en números.

Esto contrasta con muchos otros lenguajes dinámicos, donde la operación está determinada por el tipo del primer argumento. También significa que Perl tiene dos versiones de algunos operadores, una para la comparación numérica y otra para la comparación de cadenas. Por ejemplo $x == $y compara dos números para la igualdad, y $x eq $y compara dos cadenas.

Sin embargo, existen algunas excepciones: x puede ser repetición de cadena o repetición de lista, dependiendo del tipo de operando izquierdo, y &, |, ^ y ~ pueden ser operaciones de cadena o de bits numéricos.

Precedencia y asociatividad del operador

La precedencia de operadores y la asociatividad funcionan en Perl más o menos como lo hacen en matemáticas.

Precedencia del operador significa que algunos operadores se agrupan más estrechamente que otros. Por ejemplo, en 2 + 4 * 5, la multiplicación tiene mayor precedencia, por lo que 4 * 5 se agrupa como el operando de la derecha de la suma, en lugar de 2 + 4 agruparse como el operando de la izquierda de la multiplicación. Es como si la expresión estuviera escrita 2 + (4 * 5), no (2 + 4) * 5. Entonces la expresión cede 2 + 20 == 22, en vez de 6 * 5 == 30.

Asociatividad del operador define lo que sucede si se usa una secuencia de los mismos operadores uno tras otro: por lo general, se agruparán a la izquierda oa la derecha. Por ejemplo, en 9 - 3 - 2, la resta es asociativa por la izquierda, por lo que 9 - 3 se agrupa como el operando de la izquierda de la segunda resta, en lugar de 3 - 2 agruparse como el operando de la derecha de la primera resta. Es como si la expresión estuviera escrita (9 - 3) - 2, no 9 - (3 - 2). Entonces la expresión cede 6 - 2 == 4, en vez de 9 - 1 == 8.

Para los operadores simples que evalúan todos sus operandos y luego combinan los valores de alguna manera, la precedencia y la asociatividad (y paréntesis) implican algunos requisitos de orden en las operaciones de combinación. Por ejemplo, en 2 + 4 * 5, la agrupación implícita por precedencia significa que la multiplicación de 4 y 5 debe realizarse antes de la suma de 2 y 20, simplemente porque el resultado de esa multiplicación se requiere como uno de los operandos de la suma. Pero el orden de las operaciones no está completamente determinado por esto: en 2 * 2 + 4 * 5 Ambas multiplicaciones deben realizarse antes de la suma, pero la agrupación no dice nada sobre el orden en que se realizan las dos multiplicaciones. De hecho, Perl tiene una regla general de que los operandos de un operador se evalúan en orden de izquierda a derecha. Algunos operadores como &&= tener reglas de evaluación especiales que pueden hacer que un operando no se evalúe en absoluto; en general, el operador de nivel superior en una expresión tiene el control de la evaluación del operando.

Algunos operadores de comparación, como su asociatividad, cadena con algunos operadores de la misma precedencia (pero nunca con operadores de diferente precedencia). Este encadenamiento significa que cada comparación se realiza en los dos argumentos que la rodean, con cada argumento interior participando en dos comparaciones, y los resultados de la comparación están implícitamente AND. Por lo tanto "$x < $y <= $z" se comporta exactamente como "$x < $y && $y <= $z", asumiendo que "$y" es un escalar tan simple como parece. El Ying cortocircuitos como "&&" lo hace, deteniendo la secuencia de comparaciones tan pronto como se obtiene falso.

En una comparación encadenada, cada expresión de argumento se evalúa como máximo una vez, incluso si participa en dos comparaciones, pero el resultado de la evaluación se obtiene para cada comparación. (No se evalúa en absoluto si el cortocircuito significa que no es necesario para ninguna comparación). Esto es importante si el cálculo de un argumento interior es caro o no determinista. Por ejemplo,

if($x < expensive_sub() <= $z) { ...

no es del todo como

if($x < expensive_sub() && expensive_sub() <= $z) { ...

pero en cambio más cerca de

my $tmp = expensive_sub();
if($x < $tmp && $tmp <= $z) { ...

en que la subrutina solo se llama una vez. Sin embargo, tampoco es exactamente como este último código, porque la comparación encadenada en realidad no involucra ninguna variable temporal (nombrada o no): no hay asignación. Esto no hace mucha diferencia cuando la expresión es una llamada a una subrutina ordinaria, pero importa más con una subrutina lvalue, o si la expresión del argumento produce algún tipo de escalar inusual por otros medios. Por ejemplo, si la expresión del argumento produce un escalar vinculado, entonces la expresión se evalúa para producir ese escalar como máximo una vez, pero el valor de ese escalar puede obtenerse hasta dos veces, una vez para cada comparación en la que se utilice realmente.

En este ejemplo, la expresión se evalúa solo una vez y el escalar vinculado (el resultado de la expresión) se obtiene para cada comparación que lo usa.

if ($x < $tied_scalar < $z) { ...

En el siguiente ejemplo, la expresión se evalúa solo una vez y el escalar vinculado se recupera una vez como parte de la operación dentro de la expresión. El resultado de esa operación se obtiene para cada comparación, lo que normalmente no importa a menos que el resultado de la expresión también sea mágico debido a la sobrecarga del operador.

if ($x < $tied_scalar + 42 < $z) { ...

En cambio, algunos operadores son no asociativos, lo que significa que es un error de sintaxis usar una secuencia de esos operadores con la misma precedencia. Por ejemplo, "$x .. $y .. $z" es un error.

Los operadores de Perl tienen la siguiente asociatividad y precedencia, enumeradas de mayor a menor precedencia. Los operadores tomados de C mantienen la misma relación de precedencia entre sí, incluso cuando la precedencia de C es un poco complicada. (Esto hace que el aprendizaje de Perl sea más fácil para la gente de C). Con muy pocas excepciones, todos estos operan solo con valores escalares, no con valores de matriz.

left        terms and list operators (leftward)
left        ->
nonassoc    ++ --
right       **
right       ! ~  and unary + and -
left        =~ !~
left        * / % x
left        + - .
left        << >>
nonassoc    named unary operators
chained     < > <= >= lt gt le ge
chain/na    == != eq ne <=> cmp ~~
nonassoc    isa
left        &
left        | ^
left        &&
left        || //
nonassoc    ..  ...
right       ?:
right       = += -= *= etc. goto last next redo dump
left        , =>
nonassoc    list operators (rightward)
right       not
left        and
left        or xor

En las siguientes secciones, estos operadores se tratan en detalle, en el mismo orden en que aparecen en la tabla anterior.

Muchos operadores pueden estar sobrecargados de objetos. Ver sobrecarga.

Términos y operadores de lista (hacia la izquierda)

Un TERM tiene la mayor precedencia en Perl. Incluyen variables, operadores de comillas y similares, cualquier expresión entre paréntesis y cualquier función cuyos argumentos estén entre paréntesis. En realidad, no hay realmente funciones en este sentido, solo operadores de lista y operadores unarios que se comportan como funciones porque pones paréntesis alrededor de los argumentos. Todos estos están documentados en perlfunc.

Si algún operador de lista (print(), etc.) o cualquier operador unario (chdir(), etc.) va seguido de un paréntesis izquierdo como el siguiente token, el operador y los argumentos entre paréntesis se consideran de mayor precedencia, al igual que una llamada de función normal.

En ausencia de paréntesis, la precedencia de operadores de lista como print, sort, o chmod es muy alto o muy bajo dependiendo de si está mirando al lado izquierdo o al lado derecho del operador. Por ejemplo, en

@ary = (1, 3, sort 4, 2);
print @ary;         # prints 1324

las comas a la derecha del sort son evaluados antes del sort, pero las comas de la izquierda se evalúan después. En otras palabras, los operadores de lista tienden a engullir todos los argumentos que siguen y luego actúan como un TÉRMINO simple con respecto a la expresión anterior. Tenga cuidado con los paréntesis:

# These evaluate exit before doing the print:
print($foo, exit);  # Obviously not what you want.
print $foo, exit;   # Nor is this.

# These do the print before evaluating exit:
(print $foo), exit; # This is what you want.
print($foo), exit;  # Or this.
print ($foo), exit; # Or even this.

También tenga en cuenta que

print ($foo & 255) + 1, "n";

probablemente no haga lo que esperas a primera vista. Los paréntesis encierran la lista de argumentos para print que se evalúa (imprimiendo el resultado de $foo & 255). Luego se agrega uno al valor de retorno de print (generalmente 1). El resultado es algo como esto:

1 + 1, "n";    # Obviously not what you meant.

Para hacer lo que quiso decir correctamente, debe escribir:

print(($foo & 255) + 1, "n");

Consulte “Operadores unarios nombrados” para obtener más información sobre esto.

También se analizan como términos los do {} y eval {} construcciones, así como llamadas a subrutinas y métodos, y los constructores anónimos [] y {}.

Consulte también “Operadores de cotizaciones y similares a cotizaciones” al final de esta sección, así como “Operadores de E / S”.

El operador de flecha

->“es un operador de desreferencia infijo, tal como lo es en C y C ++. Si el lado derecho es un [...], {...}o un (...) subíndice, el lado izquierdo debe ser una referencia física o simbólica a una matriz, un hash o una subrutina, respectivamente. (O técnicamente hablando, una ubicación capaz de contener una referencia sólida, si es una referencia de matriz o hash que se utiliza para la asignación). Consulte perlreftut y perlref.

De lo contrario, el lado derecho es un nombre de método o una variable escalar simple que contiene el nombre del método o una referencia de subrutina, y el lado izquierdo debe ser un objeto (una referencia bendecida) o un nombre de clase (es decir, un nombre de paquete) . Ver perlobj.

Los casos de desreferenciación (a diferencia de los casos de llamadas a métodos) están algo extendidos por el postderef característica. Para los detalles de esa característica, consulte “Sintaxis de desreferencia de postfijo” en perlref.

Auto-incremento y auto-decremento

"++" y "--" funcionan como en C. Es decir, si se colocan antes de una variable, aumentan o disminuyen la variable en uno antes de devolver el valor, y si se colocan después, aumentan o disminuyen después de devolver el valor.

$i = 0;  $j = 0;
print $i++;  # prints 0
print ++$j;  # prints 1

Tenga en cuenta que, al igual que en C, Perl no define cuando la variable se incrementa o decrementa. Solo sabe que se hará en algún momento antes o después de que se devuelva el valor. Esto también significa que modificar una variable dos veces en la misma declaración conducirá a un comportamiento indefinido. Evite declaraciones como:

$i = $i ++;
print ++ $i + $i ++;

Perl no garantizará cuál es el resultado de las declaraciones anteriores.

El operador de incremento automático tiene un poco de magia adicional incorporada. Si incrementa una variable que es numérica, o que alguna vez se ha utilizado en un contexto numérico, obtiene un incremento normal. Sin embargo, si la variable se ha utilizado solo en contextos de cadena desde que se estableció, y tiene un valor que no es la cadena vacía y coincide con el patrón /^[a-zA-Z]*[0-9]*z/, el incremento se realiza como una cadena, conservando cada carácter dentro de su rango, con acarreo:

print ++($foo = "99");      # prints "100"
print ++($foo = "a0");      # prints "a1"
print ++($foo = "Az");      # prints "Ba"
print ++($foo = "zz");      # prints "aaa"

undef siempre se trata como numérico y, en particular, se cambia a 0 antes de incrementar (para que un incremento posterior de un valor indefinido regrese 0 en vez de undef).

El operador de auto-decremento no es mágico.

Exponenciación

Binario "**" es el operador de exponenciación. Se une aún más fuerte que unario menos, por lo que -2**4 es -(2**4), no (-2)**4. (Esto se implementa usando C’s pow(3) función, que en realidad funciona en dobles internamente).

Tenga en cuenta que ciertas expresiones de exponenciación están mal definidas: estas incluyen 0**0, 1**Inf, y Inf**0. No espere ningún resultado particular de estos casos especiales, los resultados dependen de la plataforma.

Operadores unarios simbólicos

Unario "!" realiza una negación lógica, es decir, “no”. Ver también not para una versión de menor precedencia de esto.

Unario "-" realiza la negación aritmética si el operando es numérico, incluida cualquier cadena que parezca un número. Si el operando es un identificador, se devuelve una cadena que consta de un signo menos concatenado con el identificador. De lo contrario, si la cadena comienza con un signo más o menos, se devuelve una cadena que comienza con el signo opuesto. Un efecto de estas reglas es que -bareword es equivalente a la cadena "-bareword". Sin embargo, si la cadena comienza con un carácter no alfabético (excluyendo "+" o "-"), Perl intentará convertir la cadena en numérica y se realizará la negación aritmética. Si la cadena no se puede convertir limpiamente a un número, Perl dará la advertencia El argumento “la cadena” no es numérico en la negación (-) en ….

Unario "~" realiza la negación bit a bit, es decir, el complemento de 1. Por ejemplo, 0666 & ~027 es 0640. (Consulte también “Aritmética de enteros” y “Operadores de cadena de bits”.) Tenga en cuenta que el ancho del resultado depende de la plataforma: ~0 tiene 32 bits de ancho en una plataforma de 32 bits, pero 64 bits de ancho en una plataforma de 64 bits, por lo que si espera un cierto ancho de bits, recuerde usar el "&" operador para enmascarar el exceso de bits.

A partir de Perl 5.28, es un error fatal intentar complementar una cadena que contiene un carácter con un valor ordinal superior a 255.

Si la función “bit a bit” está habilitada a través de use feature 'bitwise' o use v5.28, luego unario "~" siempre trata su argumento como un número y una forma alternativa del operador, "~.", siempre trata su argumento como una cadena. Entonces ~0 y ~"0" ambos darán 2 ** 32-1 en plataformas de 32 bits, mientras que ~.0 y ~."0" ambos cederán "xff". Hasta Perl 5.28, esta característica producía una advertencia en el "experimental::bitwise" categoría.

Unario "+" no tiene ningún efecto, incluso en las cuerdas. Es útil sintácticamente para separar el nombre de una función de una expresión entre paréntesis que de otro modo se interpretaría como la lista completa de argumentos de la función. (Consulte los ejemplos anteriores en “Términos y operadores de lista (hacia la izquierda)”).

Unario "" crea referencias. Si su operando es una cosa con un solo signo, crea una referencia a ese objeto. Si su operando es una lista entre paréntesis, crea referencias a las cosas mencionadas en la lista. De lo contrario, coloca su operando en el contexto de lista y crea una lista de referencias a los escalares en la lista proporcionada por el operando. Consulte perlreftut y perlref. No confunda este comportamiento con el comportamiento de la barra invertida dentro de una cadena, aunque ambas formas transmiten la noción de proteger lo siguiente de la interpolación.

Operadores vinculantes

Binario "=~" enlaza una expresión escalar a una coincidencia de patrón. Ciertas operaciones buscan o modifican la cadena $_ por defecto. Este operador hace que ese tipo de operación funcione en alguna otra cadena. El argumento correcto es un patrón de búsqueda, sustitución o transliteración. El argumento de la izquierda es lo que se supone que debe buscarse, sustituirse o transliterarse en lugar del predeterminado $_. Cuando se usa en un contexto escalar, el valor de retorno generalmente indica el éxito de la operación. Las excepciones son la sustitución (s///) y transliteración (y///) con el /r opción (no destructiva), que causa la rEl valor de retorno será el resultado de la sustitución. El comportamiento en el contexto de la lista depende del operador en particular. Consulte “Operadores Regexp Quote-Like” para más detalles y perlretut para ejemplos de uso de estos operadores.

Si el argumento correcto es una expresión en lugar de un patrón de búsqueda, sustitución o transliteración, se interpreta como un patrón de búsqueda en tiempo de ejecución. Tenga en cuenta que esto significa que su contenido se interpolará dos veces, por lo que

'\' =~ q'\';

no está bien, ya que el motor de expresiones regulares terminará intentando compilar el patrón , que considerará un error de sintaxis.

Binario "!~" es como "=~" excepto que el valor de retorno se niega en el sentido lógico.

Binario "!~" con una sustitución no destructiva (s///r) o transliteración (y///r) es un error de sintaxis.

Operadores multiplicativos

Binario "*" multiplica dos números.

Binario "https://foroayuda.es/" divide dos números.

Binario "%" es el operador de módulo, que calcula el resto de la división de su primer argumento con respecto a su segundo argumento. Operandos enteros dados $m y $n: Si $n es positivo, entonces $m % $n es $m menos el mayor múltiplo de $n Menos que o igual a $m. Si $n es negativo, entonces $m % $n es $m menos el múltiplo más pequeño de $n eso no es menos que $m (es decir, el resultado será menor o igual a cero). Si los operandos $m y $n son valores de coma flotante y el valor absoluto de $n (es decir abs($n)) es menos que (UV_MAX + 1), solo la parte entera de $m y $n se utilizará en la operación (Nota: aquí UV_MAX significa el máximo del tipo entero sin signo). Si el valor absoluto del operando derecho (abs($n)) es mayor o igual a (UV_MAX + 1), "%" calcula el resto de punto flotante $r en la ecuación ($r = $m - $i*$n) dónde $i es un número entero que hace $r tienen el mismo signo que el operando derecho $n (no como el operando izquierdo $m como la función C fmod()) y el valor absoluto menor que el de $n. Tenga en cuenta que cuando use integer está en el alcance, "%" le da acceso directo al operador de módulo implementado por su compilador de C. Este operador no está tan bien definido para operandos negativos, pero se ejecutará más rápido.

Binario x es el operador de repetición. En contexto escalar, o si el operando izquierdo no está entre paréntesis ni un qw// lista, realiza una repetición de cadena. En ese caso, proporciona contexto escalar al operando izquierdo y devuelve una cadena que consta de la cadena del operando izquierdo repetida el número de veces especificado por el operando derecho. Si el x está en contexto de lista, y el operando izquierdo está entre paréntesis o un qw// lista, realiza una repetición de lista. En ese caso, proporciona contexto de lista al operando de la izquierda y devuelve una lista que consta de la lista de operandos de la izquierda repetida el número de veces especificado por el operando de la derecha. Si el operando derecho es cero o negativo (generando una advertencia en negativo), devuelve una cadena vacía o una lista vacía, según el contexto.

print '-' x 80;             # print row of dashes

print "t" x ($tab/8), ' ' x ($tab%8);      # tab over

@ones = (1) x 80;           # a list of 80 1's
@ones = (5) x @ones;        # set all elements to 5

Operadores aditivos

Binario "+" devuelve la suma de dos números.

Binario "-" devuelve la diferencia de dos números.

Binario "." concatena dos cadenas.

Operadores de turnos

Binario "<<" devuelve el valor de su argumento de la izquierda desplazado a la izquierda por el número de bits especificado por el argumento de la derecha. Los argumentos deben ser números enteros. (Consulte también “Aritmética de enteros”).

Binario ">>" devuelve el valor de su argumento de la izquierda desplazado a la derecha por el número de bits especificado por el argumento de la derecha. Los argumentos deben ser números enteros. (Consulte también “Aritmética de enteros”).

Si use integer (ver “Aritmética de enteros”) está en vigor, entonces se utilizan enteros C con signo (cambio aritmético), de lo contrario se utilizan enteros C sin signo (cambio lógico), incluso para los cambiadores negativos. En el desplazamiento aritmético a la derecha, el bit de signo se replica a la izquierda, en el desplazamiento lógico, los bits cero entran desde la izquierda.

De cualquier manera, la implementación no generará resultados mayores que el tamaño del tipo entero con el que se construyó Perl (32 bits o 64 bits).

El desplazamiento por un número negativo de bits significa el desplazamiento inverso: el desplazamiento a la izquierda se convierte en desplazamiento a la derecha, el desplazamiento a la derecha se convierte en desplazamiento a la izquierda. Esto es diferente en C, donde el desplazamiento negativo no está definido.

Desplazarse en más bits que el tamaño de los enteros significa que la mayor parte del tiempo cero (todos los bits caen), excepto que bajo use integer sobrepasar a la derecha un cambio negativo da como resultado -1. Esto es diferente en C, donde el desplazamiento de demasiados bits no está definido. Un comportamiento común de C es “desplazamiento por módulo de bits de palabra”, de modo que, por ejemplo,

1 >> 64 == 1 >> (64 % 64) == 1 >> 0 == 1  # Common C behavior.

pero eso es completamente accidental.

Si se cansa de estar sujeto a los enteros nativos de su plataforma, el use bigint pragma elude perfectamente el problema por completo:

print 20 << 20;  # 20971520
print 20 << 40;  # 5120 on 32-bit machines,
                 # 21990232555520 on 64-bit machines
use bigint;
print 20 << 100; # 25353012004564588029934064107520

Operadores unarios nombrados

Los diversos operadores unarios nombrados se tratan como funciones con un argumento, con paréntesis opcionales.

Si algún operador de lista (print(), etc.) o cualquier operador unario (chdir(), etc.) va seguido de un paréntesis izquierdo como el siguiente token, el operador y los argumentos entre paréntesis se consideran de mayor precedencia, al igual que una llamada de función normal. Por ejemplo, debido a que los operadores unarios con nombre tienen mayor precedencia que ||:

chdir $foo    || die;       # (chdir $foo) || die
chdir($foo)   || die;       # (chdir $foo) || die
chdir ($foo)  || die;       # (chdir $foo) || die
chdir +($foo) || die;       # (chdir $foo) || die

pero porque "*" tiene mayor precedencia que los operadores con nombre:

chdir $foo * 20;    # chdir ($foo * 20)
chdir($foo) * 20;   # (chdir $foo) * 20
chdir ($foo) * 20;  # (chdir $foo) * 20
chdir +($foo) * 20; # chdir ($foo * 20)

rand 10 * 20;       # rand (10 * 20)
rand(10) * 20;      # (rand 10) * 20
rand (10) * 20;     # (rand 10) * 20
rand +(10) * 20;    # rand (10 * 20)

Con respecto a la precedencia, los operadores de prueba de archivos, como -f, -M, etc. se tratan como operadores unarios con nombre, pero no siguen esta regla funcional de paréntesis. Eso significa, por ejemplo, que -f($file).".bak" es equivalente a -f "$file.bak".

Consulte también “Términos y operadores de lista (hacia la izquierda)”.

Operadores relacionales

Los operadores de Perl que devuelven verdadero o falso generalmente devuelven valores que se pueden usar con seguridad como números. Por ejemplo, los operadores relacionales en esta sección y los operadores de igualdad en la siguiente devuelven 1 para verdadero y una versión especial de la cadena vacía definida, "", que cuenta como cero pero está exento de advertencias sobre conversiones numéricas incorrectas, al igual que "0 but true" es.

Binario "<" devuelve verdadero si el argumento de la izquierda es numéricamente menor que el de la derecha.

Binario ">" devuelve verdadero si el argumento de la izquierda es numéricamente mayor que el de la derecha.

Binario "<=" devuelve verdadero si el argumento de la izquierda es numéricamente menor o igual que el argumento de la derecha.

Binario ">=" devuelve verdadero si el argumento de la izquierda es numéricamente mayor o igual que el argumento de la derecha.

Binario "lt" devuelve verdadero si el argumento de la izquierda es una cadena menor que el argumento de la derecha.

Binario "gt" devuelve verdadero si el argumento de la izquierda es una cadena mayor que el argumento de la derecha.

Binario "le" devuelve verdadero si el argumento de la izquierda es en sentido de cadena menor o igual que el argumento de la derecha.

Binario "ge" devuelve verdadero si el argumento de la izquierda es una cadena mayor o igual que el argumento de la derecha.

Una secuencia de operadores relacionales, como "$x < $y <= $z", realiza comparaciones encadenadas, de la manera descrita anteriormente en la sección “Precedencia y asociatividad del operador”. Tenga en cuenta que no se encadenan con operadores de igualdad, que tienen menor precedencia.

Operadores de igualdad

Binario "==" devuelve verdadero si el argumento de la izquierda es numéricamente igual al argumento de la derecha.

Binario "!=" devuelve verdadero si el argumento de la izquierda no es numéricamente igual al argumento de la derecha.

Binario "eq" devuelve verdadero si el argumento de la izquierda es igual en cadena al argumento de la derecha.

Binario "ne" devuelve verdadero si el argumento de la izquierda no es igual al argumento de la derecha.

Una secuencia de los operadores de igualdad anteriores, como "$x == $y == $z", realiza comparaciones encadenadas, de la manera descrita anteriormente en la sección “Precedencia y asociatividad del operador”. Tenga en cuenta que no se encadenan con operadores relacionales, que tienen mayor precedencia.

Binario "<=>" devuelve -1, 0 o 1 dependiendo de si el argumento de la izquierda es numéricamente menor, igual o mayor que el argumento de la derecha. Si su plataforma es compatible NaN‘s (no-a-números) como valores numéricos, usándolos con "<=>" devuelve undef. NaN no es "<", "==", ">", "<=" o ">=" cualquier cosa (incluso NaN), por lo que esos 5 devuelven falso. NaN != NaN devuelve verdadero, al igual que NaN != Algo más. Si su plataforma no es compatible NaNes entonces NaN es solo una cadena con valor numérico 0.

$ perl -le '$x = "NaN"; print "No NaN support here" if $x == $x'
$ perl -le '$x = "NaN"; print "NaN support here" if $x != $x'

(Tenga en cuenta que los pragmas bigint, bigrat y bignum son compatibles "NaN".)

Binario "cmp" devuelve -1, 0 o 1 dependiendo de si el argumento de la izquierda es menor, igual o mayor que el argumento de la derecha.

Binario "~~" hace una coincidencia inteligente entre sus argumentos. La coincidencia inteligente se describe en la siguiente sección.

Los operadores de pedidos de dos caras "<=>" y "cmp"y el operador smartmatch "~~", son no asociativos entre sí y con respecto a los operadores de igualdad de la misma precedencia.

"lt", "le", "ge", "gt" y "cmp" utilizar el orden de clasificación (clasificación) especificado por el actual LC_COLLATE local si un use locale el formulario que incluye la colación está en vigor. Ver perllocale. No los mezcle con Unicode, solo utilícelos con codificaciones de configuración regional de 8 bits heredadas. El estandar Unicode::Collate y Unicode::Collate::Locale Los módulos ofrecen soluciones mucho más potentes a los problemas de intercalación.

Para realizar comparaciones que no distinguen entre mayúsculas y minúsculas, observe el “fc” en la función de plegado de mayúsculas y minúsculas perlfunc, disponible en Perl v5.16 o posterior:

if ( fc($x) eq fc($y) ) { ... }

Operador de instancia de clase

Binario isa se evalúa como verdadero cuando el argumento de la izquierda es una instancia de objeto de la clase (o una subclase derivada de esa clase) dada por el argumento de la derecha. Si el argumento de la izquierda no está definido, no es una instancia de objeto bendecido, ni se deriva de la clase dada por el argumento de la derecha, el operador se evalúa como falso. El argumento correcto puede dar la clase como una palabra simple o una expresión escalar que produce un nombre de clase de cadena:

if( $obj isa Some::Class ) { ... }

if( $obj isa "Different::Class" ) { ... }
if( $obj isa $name_of_class ) { ... }

Esta es una función experimental y está disponible en Perl 5.31.6 cuando está habilitada por use feature 'isa'. Emite una advertencia en el experimental::isa categoría.

Operador de Smartmatch

Primero disponible en Perl 5.10.1 (la versión 5.10.0 se comportó de manera diferente), binario ~~ hace un “smartmatch” entre sus argumentos. Esto se usa principalmente implícitamente en el when constructo descrito en Perlsyn, aunque no todos when las cláusulas llaman al operador smartmatch. Único entre todos los operadores de Perl, el operador de smartmatch puede recurrir. El operador de smartmatch es experimental y su comportamiento está sujeto a cambios.

También es único en el sentido de que todos los demás operadores de Perl imponen un contexto (generalmente un contexto de cadena o numérico) en sus operandos, convirtiendo automáticamente esos operandos a esos contextos impuestos. Por el contrario, smartmatch infiere contextos de los tipos reales de sus operandos y utiliza ese tipo de información para seleccionar un mecanismo de comparación adecuado.

los ~~ El operador compara sus operandos “polimórficamente”, determinando cómo compararlos de acuerdo con sus tipos reales (numérico, cadena, matriz, hash, etc.). Como los operadores de igualdad con los que comparte la misma precedencia, ~~ devuelve 1 para verdadero y "" por falso. A menudo, es mejor leerlo en voz alta como “en”, “dentro de” o “está contenido en”, porque el operando izquierdo a menudo se busca dentro el operando correcto. Eso hace que el orden de los operandos al operando de coincidencia inteligente a menudo sea opuesto al del operador de coincidencia normal. En otras palabras, lo “más pequeño” generalmente se coloca en el operando izquierdo y el más grande en el derecho.

El comportamiento de un smartmatch depende del tipo de cosas que sean sus argumentos, según lo determinado por la siguiente tabla. La primera fila de la tabla cuyos tipos se aplican determina el comportamiento de Smartmatch. Debido a que lo que realmente sucede está determinado principalmente por el tipo del segundo operando, la tabla se ordena por el operando derecho en lugar de por el izquierdo.

Left      Right      Description and pseudocode
===============================================================
Any       undef      check whether Any is undefined
               like: !defined Any

Any       Object     invoke ~~ overloading on Object, or die

Right operand is an ARRAY:

Left      Right      Description and pseudocode
===============================================================
ARRAY1    ARRAY2     recurse on paired elements of ARRAY1 and ARRAY2[2]
               like: (ARRAY1[0] ~~ ARRAY2[0])
                       && (ARRAY1[1] ~~ ARRAY2[1]) && ...
HASH      ARRAY      any ARRAY elements exist as HASH keys
               like: grep { exists HASH->{$_} } ARRAY
Regexp    ARRAY      any ARRAY elements pattern match Regexp
               like: grep { /Regexp/ } ARRAY
undef     ARRAY      undef in ARRAY
               like: grep { !defined } ARRAY
Any       ARRAY      smartmatch each ARRAY element[3]
               like: grep { Any ~~ $_ } ARRAY

Right operand is a HASH:

Left      Right      Description and pseudocode
===============================================================
HASH1     HASH2      all same keys in both HASHes
               like: keys HASH1 ==
                        grep { exists HASH2->{$_} } keys HASH1
ARRAY     HASH       any ARRAY elements exist as HASH keys
               like: grep { exists HASH->{$_} } ARRAY
Regexp    HASH       any HASH keys pattern match Regexp
               like: grep { /Regexp/ } keys HASH
undef     HASH       always false (undef can't be a key)
               like: 0 == 1
Any       HASH       HASH key existence
               like: exists HASH->{Any}

Right operand is CODE:

Left      Right      Description and pseudocode
===============================================================
ARRAY     CODE       sub returns true on all ARRAY elements[1]
               like: !grep { !CODE->($_) } ARRAY
HASH      CODE       sub returns true on all HASH keys[1]
               like: !grep { !CODE->($_) } keys HASH
Any       CODE       sub passed Any returns true
               like: CODE->(Any)

El operando derecho es una expresión regular:

Left      Right      Description and pseudocode
===============================================================
ARRAY     Regexp     any ARRAY elements match Regexp
               like: grep { /Regexp/ } ARRAY
HASH      Regexp     any HASH keys match Regexp
               like: grep { /Regexp/ } keys HASH
Any       Regexp     pattern match
               like: Any =~ /Regexp/

Other:

Left      Right      Description and pseudocode
===============================================================
Object    Any        invoke ~~ overloading on Object,
                     or fall back to...

Any       Num        numeric equality
                like: Any == Num
Num       nummy[4]    numeric equality
                like: Num == nummy
undef     Any        check whether undefined
                like: !defined(Any)
Any       Any        string equality
                like: Any eq Any

Notas:

1. Coincidencia de hashes o matrices vacías.
2. Es decir, cada elemento coincide inteligentemente con el elemento del mismo índice en la otra matriz.[3]
3. Si se encuentra una referencia circular, recurra a la igualdad referencial.
4. O un número real o una cadena que parece uno.

Smartmatch elimina implícitamente cualquier referencia de matriz o hash no bendecida, por lo que HASH y ARRAY las entradas se aplican en esos casos. Para benditas referencias, el Object se aplican entradas. Las coincidencias inteligentes que involucran hashes solo consideran claves hash, nunca valores hash.

La entrada del código “me gusta” no siempre es una interpretación exacta. Por ejemplo, el operador de smartmatch cortocircuita siempre que sea posible, pero grep no. También, grep en contexto escalar devuelve el número de coincidencias, pero ~~ devuelve solo verdadero o falso.

A diferencia de la mayoría de los operadores, el operador de smartmatch sabe tratar undef especialmente:

use v5.10.1;
@array = (1, 2, 3, undef, 4, 5);
say "some elements undefined" if undef ~~ @array;

Cada operando se considera en un contexto escalar modificado, la modificación es que las variables de matriz y hash se pasan por referencia al operador, que implícitamente las desreferencia. Ambos elementos de cada par son iguales:

use v5.10.1;

my %hash = (red    => 1, blue   => 2, green  => 3,
            orange => 4, yellow => 5, purple => 6,
            black  => 7, grey   => 8, white  => 9);

my @array = qw(red blue green);

say "some array elements in hash keys" if  @array ~~  %hash;
say "some array elements in hash keys" if @array ~~ %hash;

say "red in array" if "red" ~~  @array;
say "red in array" if "red" ~~ @array;

say "some keys end in e" if /e$/ ~~  %hash;
say "some keys end in e" if /e$/ ~~ %hash;

Dos matrices se emparejan inteligentemente si cada elemento de la primera matriz empareja inteligentemente (es decir, está “en”) el elemento correspondiente en la segunda matriz, de forma recursiva.

use v5.10.1;
my @little = qw(red blue green);
my @bigger = ("red", "blue", [ "orange", "green" ] );
if (@little ~~ @bigger) {  # true!
    say "little is contained in bigger";
}

Debido a que el operador smartmatch recurre en matrices anidadas, esto aún informará que “rojo” está en la matriz.

use v5.10.1;
my @array = qw(red blue green);
my $nested_array = [[[[[[[ @array ]]]]]]];
say "red in array" if "red" ~~ $nested_array;

Si dos matrices se emparejan de forma inteligente entre sí, entonces son copias profundas de los valores de cada uno, como informa este ejemplo:

use v5.12.0;
my @a = (0, 1, 2, [3, [4, 5], 6], 7);
my @b = (0, 1, 2, [3, [4, 5], 6], 7);

if (@a ~~ @b && @b ~~ @a) {
    say "a and b are deep copies of each other";
}
elsif (@a ~~ @b) {
    say "a smartmatches in b";
}
elsif (@b ~~ @a) {
    say "b smartmatches in a";
}
else {
    say "a and b don't smartmatch each other at all";
}

Si tuvieras que establecer $b[3] = 4, luego, en lugar de informar que “ayb son copias profundas el uno del otro”, ahora Informes que "b smartmatches in a". Eso es porque la posición correspondiente en @a contiene una matriz que (eventualmente) tiene un 4.

La comparación inteligente de un hash con otro informa si ambos contienen las mismas claves, ni más ni menos. Esto podría usarse para ver si dos registros tienen los mismos nombres de campo, sin importar los valores que puedan tener esos campos. Por ejemplo:

use v5.10.1;
sub make_dogtag {
    state $REQUIRED_FIELDS = { name=>1, rank=>1, serial_num=>1 };

    my ($class, $init_fields) = @_;

    die "Must supply (only) name, rank, and serial number"
        unless $init_fields ~~ $REQUIRED_FIELDS;

    ...
}

Sin embargo, esto solo hace lo que quieres decir si $init_fields es de hecho una referencia hash. La condición $init_fields ~~ $REQUIRED_FIELDS también permite las cuerdas "name", "rank", "serial_num" así como cualquier referencia de matriz que contenga "name" o "rank" o "serial_num" en cualquier lugar para pasar.

El operador smartmatch se utiliza con mayor frecuencia como operador implícito de un when cláusula. Consulte la sección sobre “Declaraciones de cambio” en perlsyn.

Coincidencia inteligente de objetos

Para evitar depender de la representación subyacente de un objeto, si el operando derecho de smartmatch es un objeto que no se sobrecarga ~~, genera la excepción “Smartmatching a non-overloaded object breaks encapsulation“. Eso es porque uno no tiene por qué investigar para ver si algo está” en “un objeto. Todo esto es ilegal en objetos sin un ~~ sobrecarga:

 %hash ~~ $object
    42 ~~ $object
"fred" ~~ $object

Sin embargo, puede cambiar la forma en que un objeto se empareja de forma inteligente sobrecargando el ~~ operador. Esto permite extender la semántica habitual de smartmatch. Para los objetos que tienen un ~~ sobrecarga, ver sobrecarga.

Se permite usar un objeto como operando izquierdo, aunque no es muy útil. Las reglas de Smartmatching tienen prioridad sobre la sobrecarga, por lo que incluso si el objeto del operando izquierdo tiene una sobrecarga de Smartmatch, esto se ignorará. Un operando izquierdo que es un objeto no sobrecargado recurre a una cadena o comparación numérica de lo que sea ref regresa el operador. Eso significa que

$object ~~ X

lo hace no invocar el método de sobrecarga con X como argumento. En cambio, la tabla anterior se consulta con normalidad y se basa en el tipo de X, la sobrecarga puede invocarse o no. Para cadenas o números simples, “in” se convierte en equivalente a esto:

$object ~~ $number          ref($object) == $number
$object ~~ $string          ref($object) eq $string

Por ejemplo, esto informa que el mango huele a IOish (¡pero por favor, no hagas esto!):

use IO::Handle;
my $fh = IO::Handle->new();
if ($fh ~~ /bIOb/) {
    say "handle smells IOish";
}

Eso es porque trata $fh como una cuerda como "IO::Handle=GLOB(0x8039e0)", luego el patrón coincide con eso.

Bit a bit y

Binario "&" devuelve sus operandos AND juntos bit a bit. Aunque actualmente no se emite ninguna advertencia, el resultado no está bien definido cuando esta operación se realiza en operandos que no son números (consulte “Aritmética de enteros”) ni cadenas de bits (consulte “Operadores de cadenas de bits”).

Tenga en cuenta que "&" tiene menor prioridad que los operadores relacionales, por lo que, por ejemplo, los paréntesis son esenciales en una prueba como

print "Evenn" if ($x & 1) == 0;

Si la función “bit a bit” está habilitada a través de use feature 'bitwise' o use v5.28, entonces este operador siempre trata sus operandos como números. Antes de Perl 5.28, esta característica producía una advertencia en el "experimental::bitwise" categoría.

O bit a bit y O exclusivo

Binario "|" devuelve sus operandos OR juntos bit a bit.

Binario "^" devuelve sus operandos XOR juntos bit a bit.

Aunque actualmente no se genera ninguna advertencia, los resultados no están bien definidos cuando estas operaciones se realizan en operandos que no son números (consulte “Aritmética de enteros”) ni cadenas de bits (consulte “Operadores de cadenas de bits”).

Tenga en cuenta que "|" y "^" tienen menor prioridad que los operadores relacionales, por lo que, por ejemplo, los paréntesis son esenciales en una prueba como

print "falsen" if (8 | 2) != 10;

Si la función “bit a bit” está habilitada a través de use feature 'bitwise' o use v5.28, entonces este operador siempre trata sus operandos como números. Antes de Perl 5.28. esta característica produjo una advertencia en el "experimental::bitwise" categoría.

Lógico estilo C y

Binario "&&" realiza una operación Y lógica de cortocircuito. Es decir, si el operando izquierdo es falso, el operando derecho ni siquiera se evalúa. El contexto escalar o de lista se propaga hacia el operando derecho si se evalúa.

O lógico de estilo C

Binario "||" realiza una operación OR lógica de cortocircuito. Es decir, si el operando izquierdo es verdadero, el operando derecho ni siquiera se evalúa. El contexto escalar o de lista se propaga hacia el operando derecho si se evalúa.

Definido lógico-Or

Aunque no tiene equivalente directo en C, Perl // El operador está relacionado con su estilo C “o”. De hecho, es exactamente lo mismo que ||, excepto que prueba la definición del lado izquierdo en lugar de su verdad. Por lo tanto, EXPR1 // EXPR2 devuelve el valor de EXPR1 si está definido, de lo contrario, el valor de EXPR2 es regresado. (EXPR1 se evalúa en contexto escalar, EXPR2 en el contexto de // sí mismo). Por lo general, este es el mismo resultado que defined(EXPR1) ? EXPR1 : EXPR2 (excepto que la forma del operador ternario se puede usar como un valor l, mientras que EXPR1 // EXPR2 no poder). Esto es muy útil para proporcionar valores predeterminados para variables. Si realmente desea probar si al menos uno de $x y $y está definido, usar defined($x // $y).

los ||, // y && Los operadores devuelven el último valor evaluado (a diferencia de C || y &&, que devuelven 0 o 1). Por lo tanto, una forma razonablemente portátil de encontrar el directorio de inicio podría ser:

$home =  $ENV{HOME}
      // $ENV{LOGDIR}
      // (getpwuid($<))[7]
      // die "You're homeless!n";

En particular, esto significa que no debe usar esto para seleccionar entre dos agregados para la asignación:

@a = @b || @c;            # This doesn't do the right thing
@a = scalar(@b) || @c;    # because it really means this.
@a = @b ? @b : @c;        # This works fine, though.

Como alternativas a && y || cuando se utiliza para controlar el flujo, Perl proporciona la and y or operadores (ver más abajo). El comportamiento de cortocircuito es idéntico. La precedencia de "and" y "or" es mucho más bajo, sin embargo, para que pueda usarlos de manera segura después de un operador de lista sin la necesidad de paréntesis:

unlink "alpha", "beta", "gamma"
        or gripe(), next LINE;

Con los operadores de estilo C que se habrían escrito así:

unlink("alpha", "beta", "gamma")
        || (gripe(), next LINE);

Sería aún más legible escribir eso de esta manera:

unless(unlink("alpha", "beta", "gamma")) {
    gripe();
    next LINE;
}

Utilizando "or" para la asignación es poco probable que haga lo que quiere; vea abajo.

Operadores de rango

Binario ".." es el operador de rango, que en realidad son dos operadores diferentes según el contexto. En el contexto de la lista, devuelve una lista de valores contando (de a uno) desde el valor de la izquierda al valor de la derecha. Si el valor de la izquierda es mayor que el valor de la derecha, devuelve la lista vacía. El operador de rango es útil para escribir foreach (1..10) bucles y para realizar operaciones de corte en matrices. En la implementación actual, no se crea una matriz temporal cuando el operador de rango se usa como expresión en foreach bucles, pero las versiones anteriores de Perl pueden quemar mucha memoria cuando escribe algo como esto:

for (1 .. 1_000_000) {
    # code
}

El operador de rango también trabaja en cadenas, usando el mágico incremento automático, ver más abajo.

En contexto escalar, ".." devuelve un valor booleano. El operador es biestable, como un flip-flop, y emula el operador de rango de línea (coma) de sed, awky varios editores. Cada ".." El operador mantiene su propio estado booleano, incluso a través de llamadas a una subrutina que lo contiene. Es falso siempre que su operando izquierdo sea falso. Una vez que el operando izquierdo es verdadero, el operador de rango permanece verdadero hasta que el operando derecho es verdadero, DESPUÉS que el operador de rango se vuelve falso nuevamente. No se vuelve falso hasta la próxima vez que se evalúa el operador de rango. Puede probar el operando correcto y volverse falso en la misma evaluación en la que se convirtió en verdadero (como en awk), pero aún devuelve verdadero una vez. Si no quiere que pruebe el operando correcto hasta la próxima evaluación, como en sed, solo usa tres puntos ("...") en lugar de dos. En todos los demás aspectos, "..." se comporta como ".." lo hace.

El operando derecho no se evalúa mientras el operador está en el estado “falso”, y el operando izquierdo no se evalúa mientras el operador está en el estado “verdadero”. La precedencia es un poco menor que || y &&. El valor devuelto es la cadena vacía para falso o un número de secuencia (que comienza con 1) para verdadero. El número de secuencia se restablece para cada rango encontrado. El número de secuencia final en un rango tiene la cadena "E0" agregado a él, lo que no afecta su valor numérico, pero le da algo para buscar si desea excluir el punto final. Puede excluir el punto de inicio esperando que el número de secuencia sea mayor que 1.

Si cualquiera de los operandos de escalar ".." es una expresión constante, ese operando se considera verdadero si es igual (==) al número de línea de entrada actual (el $. variable).

Para ser pedante, la comparación es en realidad int(EXPR) == int(EXPR), pero eso solo es un problema si usa una expresión de punto flotante; cuando se usa implícitamente $. como se describe en el párrafo anterior, la comparación es int(EXPR) == int($.) que es solo un problema cuando $. está establecido en un valor de punto flotante y no está leyendo de un archivo. Es más, "span" .. "spat" o 2.18 .. 3.14 no hará lo que desea en el contexto escalar porque cada uno de los operandos se evalúa utilizando su representación entera.

Ejemplos:

Como operador escalar:

if (101 .. 200) { print; } # print 2nd hundred lines, short for
                           #  if ($. == 101 .. $. == 200) { print; }

next LINE if (1 .. /^$/);  # skip header lines, short for
                           #   next LINE if ($. == 1 .. /^$/);
                           # (typically in a loop labeled LINE)

s/^/> / if (/^$/ .. eof());  # quote body

# parse mail messages
while (<>) {
    $in_header =   1  .. /^$/;
    $in_body   = /^$/ .. eof;
    if ($in_header) {
        # do something
    } else { # in body
        # do something else
    }
} continue {
    close ARGV if eof;             # reset $. each file
}

Aquí hay un ejemplo simple para ilustrar la diferencia entre los dos operadores de rango:

@lines = ("   - Foo",
          "01 - Bar",
          "1  - Baz",
          "   - Quux");

foreach (@lines) {
    if (/0/ .. /1/) {
        print "$_n";
    }
}

Este programa imprimirá solo la línea que contiene “Bar”. Si el operador de rango se cambia a ..., también imprimirá la línea “Baz”.

Y ahora algunos ejemplos como operador de lista:

for (101 .. 200) { print }      # print $_ 100 times
@foo = @foo[0 .. $#foo];        # an expensive no-op
@foo = @foo[$#foo-4 .. $#foo];  # slice last 5 items

Dado que cada operando se evalúa en forma de entero, 2.18 .. 3.14 devolverá dos elementos en el contexto de la lista.

@list = (2.18 .. 3.14); # same as @list = (2 .. 3);

El operador de rango en el contexto de lista puede hacer uso del algoritmo mágico de incremento automático si ambos operandos son cadenas, sujeto a las siguientes reglas:

  • Con una excepción (a continuación), si ambas cadenas parecen números para Perl, el incremento mágico no se aplicará y las cadenas se tratarán como números (más específicamente, enteros) en su lugar.

    Por ejemplo, "-2".."2" es lo mismo que -2..2, y "2.18".."3.14" produce 2, 3.

  • La excepción a lo anterior La regla es cuando la cuerda de la izquierda comienza con 0 y tiene más de un carácter, en este caso el incremento mágico voluntad ser aplicado, aunque cadenas como "01" normalmente se vería como un número para Perl.

    Por ejemplo, "01".."04" produce "01", "02", "03", "04", y "00".."-1" produce "00" mediante "99" – esto puede parecer sorprendente, pero consulte las siguientes reglas sobre por qué funciona de esta manera. Para obtener fechas con ceros a la izquierda, puede decir:

    @z2 = ("01" .. "31");
    print $z2[$mday];

    Si desea forzar que las cadenas se interpreten como números, podría decir

    @numbers = ( 0+$first .. 0+$last );
  • Si el valor inicial especificado no forma parte de una secuencia de incremento mágico (es decir, una cadena no vacía que coincide /^[a-zA-Z]*[0-9]*z/), solo se devolverá el valor inicial.

    Por ejemplo, "ax".."az" produce "ax", "ay", "az", pero "*x".."az" produce solo "*x".

  • Para otros valores iniciales que son cadenas que siguen las reglas del incremento mágico, se devolverá la secuencia correspondiente.

    Por ejemplo, puedes decir

    @alphabet = ("A" .. "Z");

    para obtener todas las letras normales del alfabeto inglés, o

    $hexdigit = (0 .. 9, "a" .. "f")[$num & 15];

    para obtener un dígito hexadecimal.

  • Si el valor final especificado no está en la secuencia que produciría el incremento mágico, la secuencia continúa hasta que el siguiente valor sea más largo que el valor final especificado. Si la longitud de la cadena final es más corta que la primera, se devuelve la lista vacía.

    Por ejemplo, "a".."--" es lo mismo que "a".."zz", "0".."xx" produce "0" mediante "99", y "aaa".."--" devuelve la lista vacía.

A partir de Perl 5.26, el operador de rango de contexto de lista en cadenas funciona como se esperaba en el alcance de "use feature 'unicode_strings". En versiones anteriores, y fuera del alcance de esa característica, exhibe “El” Error Unicode “” en perlunicode: su comportamiento depende de la codificación interna del punto final del rango.

Porque el incremento mágico solo funciona en cadenas no vacías que coinciden /^[a-zA-Z]*[0-9]*z/, lo siguiente solo devolverá un alfa:

use charnames "greek";
my @greek_small =  ("N{alpha}" .. "N{omega}");

Para obtener las 25 letras griegas minúsculas tradicionales, incluidos ambos sigmas, puede usar esto en su lugar:

use charnames "greek";
my @greek_small =  map { chr } ( ord("N{alpha}")
                                    ..
                                 ord("N{omega}")
                               );

Sin embargo, debido a que hay muchos otros caracteres griegos en minúscula además de esos, para hacer coincidir los caracteres griegos en minúscula en una expresión regular, puede utilizar el patrón /(?:(?=p{Greek})p{Lower})+/ (o la función experimental /(?[ p{Greek} & p{Lower} ])+/).

Operador condicional

Ternario "?:" es el operador condicional, al igual que en C. Funciona de forma muy similar a un if-then-else. Si el argumento antes del ? es cierto, el argumento antes de la : se devuelve, de lo contrario, el argumento después de la : es regresado. Por ejemplo:

printf "I have %d dog%s.n", $n,
        ($n == 1) ? "" : "s";

El contexto escalar o de lista se propaga hacia abajo en el segundo o tercer argumento, el que se seleccione.

$x = $ok ? $y : $z;  # get a scalar
@x = $ok ? @y : @z;  # get an array
$x = $ok ? @y : @z;  # oops, that's just a count!

El operador puede asignarse a si tanto el segundo como el tercer argumento son valores legales (lo que significa que puede asignarles):

($x_or_y ? $x : $y) = $z;

Debido a que este operador produce un resultado asignable, el uso de asignaciones sin paréntesis lo meterá en problemas. Por ejemplo, esto:

$x % 2 ? $x += 10 : $x += 2

Realmente significa esto:

(($x % 2) ? ($x += 10) : $x) += 2

En vez de esto:

($x % 2) ? ($x += 10) : ($x += 2)

Eso probablemente debería escribirse de manera más simple como:

$x += ($x % 2) ? 10 : 2;

Operadores de Asignación

"=" es el operador de asignación ordinario.

Los operadores de asignación funcionan como en C. Es decir,

$x += 2;

es equivalente a

$x = $x + 2;

aunque sin duplicar los efectos secundarios que podría desencadenar la desreferenciación del valor l, como tie(). Otros operadores de asignación funcionan de manera similar. Se reconocen los siguientes:

**=    +=    *=    &=    &.=    <<=    &&=
       -=    /=    |=    |.=    >>=    ||=
       .=    %=    ^=    ^.=           //=
             x=

Aunque están agrupados por familia, todos tienen prioridad de asignación. Estos operadores de asignación combinados solo pueden operar en escalares, mientras que el operador de asignación ordinario puede asignar a matrices, hashes, listas e incluso referencias. (Consulte “Contexto” y “Constructores de valor de lista” en perldata y “Asignación a referencias” en perlref).

A diferencia de C, el operador de asignación escalar produce un valor l válido. Modificar una asignación equivale a realizar la asignación y luego modificar la variable a la que se asignó. Esto es útil para modificar una copia de algo, como esto:

($tmp = $global) =~ tr/13579/24680/;

Aunque a partir de 5.14, eso también se puede lograr de esta manera:

use v5.14;
$tmp = ($global =~  tr/13579/24680/r);

Igualmente,

($x += 2) *= 3;

es equivalente a

$x += 2;
$x *= 3;

De manera similar, una asignación de lista en contexto de lista produce la lista de valores l asignados a, y una asignación de lista en contexto escalar devuelve el número de elementos producidos por la expresión en el lado derecho de la asignación.

Los tres operadores de asignación bit a bit con puntos (&.= |.= ^.=) son nuevas en Perl 5.22. Consulte “Operadores de cadenas de bits”.

Operador de coma

Binario "," es el operador de coma. En contexto escalar, evalúa su argumento izquierdo, descarta ese valor, luego evalúa su argumento derecho y devuelve ese valor. Esto es como el operador de coma de C.

En el contexto de la lista, es solo el separador de argumentos de la lista e inserta ambos argumentos en la lista. Estos argumentos también se evalúan de izquierda a derecha.

los => operador (a veces pronunciado “coma gruesa”) es un sinónimo de la coma, excepto que hace que una palabra a su izquierda se interprete como una cadena si comienza con una letra o un guión bajo y está compuesta solo de letras, dígitos y guiones bajos. Esto incluye operandos que de otro modo podrían interpretarse como operadores, constantes, cadenas v de un solo número o llamadas a funciones. Si tiene dudas sobre este comportamiento, el operando izquierdo se puede citar explícitamente.

De lo contrario, el => El operador se comporta exactamente como el operador de coma o el separador de argumentos de lista, según el contexto.

Por ejemplo:

use constant FOO => "something";

my %h = ( FOO => 23 );

es equivalente a:

my %h = ("FOO", 23);

Está NO:

my %h = ("something", 23);

los => El operador es útil para documentar la correspondencia entre claves y valores en hashes y otros elementos emparejados en listas.

%hash = ( $key => $value );
login( $username => $password );

El comportamiento de cotización especial ignora la precedencia y, por lo tanto, puede aplicarse a parte del operando izquierdo:

print time.shift => "bbb";

Ese ejemplo imprime algo como "1314363215shiftbbb", porque el => cita implícitamente el shift inmediatamente a su izquierda, ignorando el hecho de que time.shift es el operando izquierdo completo.

Operadores de lista (hacia la derecha)

En el lado derecho de un operador de lista, la coma tiene una precedencia muy baja, de modo que controla todas las expresiones separadas por comas que se encuentran allí. Los únicos operadores con menor precedencia son los operadores lógicos "and", "or", y "not", que puede usarse para evaluar llamadas a operadores de lista sin la necesidad de paréntesis:

open HANDLE, "< :encoding(UTF-8)", "filename"
    or die "Can't open: $!n";

Sin embargo, algunas personas encuentran ese código más difícil de leer que escribirlo entre paréntesis:

open(HANDLE, "< :encoding(UTF-8)", "filename")
    or die "Can't open: $!n";

en cuyo caso también podría utilizar el más habitual "||" operador:

open(HANDLE, "< :encoding(UTF-8)", "filename")
    || die "Can't open: $!n";

Consulte también la discusión sobre los operadores de lista en “Términos y operadores de lista (hacia la izquierda)”.

Lógico no

Unario "not" devuelve la negación lógica de la expresión a su derecha. Es el equivalente de "!" excepto por la muy baja precedencia.

Lógico y

Binario "and" devuelve la conjunción lógica de las dos expresiones circundantes. Es equivalente a && excepto por la muy baja precedencia. Esto significa que se produce un cortocircuito: la expresión de la derecha se evalúa solo si la expresión de la izquierda es verdadera.

O lógico y exclusivo O

Binario "or" devuelve la disyunción lógica de las dos expresiones circundantes. Es equivalente a || excepto por la muy baja precedencia. Esto lo hace útil para controlar el flujo:

print FH $data              or die "Can't write to FH: $!";

Esto significa que se produce un cortocircuito: la expresión de la derecha se evalúa solo si la expresión de la izquierda es falsa. Debido a su precedencia, debe tener cuidado de no usarlo como reemplazo del || operador. Por lo general, funciona mejor para el control de flujo que en las asignaciones:

$x = $y or $z;              # bug: this is wrong
($x = $y) or $z;            # really means this
$x = $y || $z;              # better written this way

Sin embargo, cuando se trata de una asignación de contexto de lista y está intentando usar || para controlar el flujo, probablemente necesite "or" para que la asignación tenga mayor prioridad.

@info = stat($file) || die;     # oops, scalar sense of stat!
@info = stat($file) or die;     # better, now @info gets its due

Por otra parte, siempre puedes usar paréntesis.

Binario "xor" devuelve el OR exclusivo de las dos expresiones circundantes. No puede cortocircuitar (por supuesto).

No hay un operador de baja precedencia para definido-OR.

C Operadores que faltan en Perl

Esto es lo que C tiene y Perl no:

unario y

Dirección del operador. (Pero mira el "" operador para tomar una referencia.)

unario *

Operador de dirección de desreferencia. (Los operadores de desreferenciación de prefijos de Perl se escriben: $, @, %, y &.)

(ESCRIBE)

Operador de fundición tipográfica.

Operadores de cotizaciones y cotizaciones

Si bien generalmente pensamos en las comillas como valores literales, en Perl funcionan como operadores, proporcionando varios tipos de capacidades de interpolación y coincidencia de patrones. Perl proporciona caracteres de comillas habituales para estos comportamientos, pero también le ofrece una forma de elegir su carácter de comillas para cualquiera de ellos. En la siguiente tabla, un {} representa cualquier par de delimitadores que elija.

Customary  Generic        Meaning        Interpolates
    ''       q{}          Literal             no
    ""      qq{}          Literal             yes
    ``      qx{}          Command             yes*
            qw{}         Word list            no
    //       m{}       Pattern match          yes*
            qr{}          Pattern             yes*
             s{}{}      Substitution          yes*
            tr{}{}    Transliteration         no (but see below)
             y{}{}    Transliteration         no (but see below)
    <<EOF                 here-doc            yes*

    * unless the delimiter is ''.

Los delimitadores sin corchetes usan el mismo carácter hacia adelante y hacia atrás, pero los cuatro tipos de corchetes ASCII (redondo, ángulo, cuadrado, rizado) todos anidan, lo que significa que

q{foo{bar}baz}

es lo mismo que

'foo{bar}baz'

Sin embargo, tenga en cuenta que esto no siempre funciona para citar código Perl:

$s = q{ if($x eq "}") ... }; # WRONG

es un error de sintaxis. los Text::Balanced módulo (estándar a partir de v5.8, y de CPAN antes de esa fecha) puede hacer esto correctamente.

Puede (y en algunos casos, debe) ser un espacio en blanco entre el operador y los caracteres entre comillas, excepto cuando # se utiliza como carácter de cita. q#foo# se analiza como la cadena foo, tiempo q #foo# es el operador q seguido de un comentario. Su argumento se tomará de la siguiente línea. Esto le permite escribir:

s {foo}  # Replace foo
  {bar}  # with bar.

Los casos en los que se deben usar espacios en blanco son cuando el carácter entre comillas es un carácter de palabra (lo que significa que coincide /w/):

q XfooX # Works: means the string 'foo'
qXfooX  # WRONG!

Las siguientes secuencias de escape están disponibles en construcciones que se interpolan y en transliteraciones cuyos delimitadores no son comillas simples ("'").

Sequence     Note  Description
t                  tab               (HT, TAB)
n                  newline           (NL)
r                  return            (CR)
f                  form feed         (FF)
b                  backspace         (BS)
a                  alarm (bell)      (BEL)
e                  escape            (ESC)
x{263A}     [1,8]  hex char          (example shown: SMILEY)
x1b         [2,8]  restricted range hex char (example: ESC)
N{name}     [3]    named Unicode character or character sequence
N{U+263D}   [4,8]  Unicode character (example: FIRST QUARTER MOON)
c[          [5]    control char      (example: chr(27))
o{23072}    [6,8]  octal char        (example: SMILEY)
033         [7,8]  restricted range octal char  (example: ESC)
[1]

El resultado es el carácter especificado por el número hexadecimal entre llaves. Ver “[8]”a continuación para obtener detalles sobre qué personaje.

Solo los dígitos hexadecimales son válidos entre llaves. Si se encuentra un carácter no válido, se emitirá una advertencia y el carácter no válido y todos los caracteres subsiguientes (válidos o no válidos) entre llaves se descartarán.

Si no hay dígitos válidos entre llaves, el carácter generado es el carácter NULL (x{00}). Sin embargo, una llave vacía explícita (x{}) no provocará una advertencia (actualmente).

[2]

El resultado es el carácter especificado por el número hexadecimal en el rango de 0x00 a 0xFF. Ver “[8]”a continuación para obtener detalles sobre qué personaje.

Solo los dígitos hexadecimales son válidos siguiendo x. Cuando x va seguido de menos de dos dígitos válidos, los dígitos válidos se rellenarán con ceros. Esto significa que x7 será interpretado como x07, y solo "x" será interpretado como x00. Excepto al final de una cadena, tener menos de dos dígitos válidos resultará en una advertencia. Tenga en cuenta que aunque la advertencia dice que se ignora el carácter ilegal, solo se ignora como parte del escape y se seguirá utilizando como el carácter posterior de la cadena. Por ejemplo:

Original    Result    Warns?
"x7"       "x07"    no
"x"        "x00"    no
"x7q"      "x07q"   yes
"xq"       "x00q"   yes
[3]

El resultado es el carácter Unicode o la secuencia de caracteres dada por nombre. Ver nombres de caracteres.

[4]

N{U+hexadecimal number} significa el carácter Unicode cuyo punto de código Unicode es número hexadecimal.

[5]

El personaje que sigue c se asigna a algún otro carácter como se muestra en la tabla:

Sequence   Value
  [email protected]      chr(0)
  cA      chr(1)
  ca      chr(1)
  cB      chr(2)
  cb      chr(2)
  ...
  cZ      chr(26)
  cz      chr(26)
  c[      chr(27)
                    # See below for chr(28)
  c]      chr(29)
  c^      chr(30)
  c_      chr(31)
  c?      chr(127) # (on ASCII platforms; see below for link to
                    #  EBCDIC discussion)

En otras palabras, es el carácter cuyo punto de código ha tenido 64 xor con su mayúscula. c? es DELETE en plataformas ASCII porque ord("?") ^ 64 es 127, y [email protected] es NULL porque el ord de "@" es 64, por lo que xor’ing 64 en sí mismo produce 0.

También, cX rendimientos chr(28) . "X" para cualquier X, pero no puede ir al final de una cadena, porque la barra invertida se analizaría como un escape de la comilla final.

En las plataformas ASCII, los caracteres resultantes de la lista anterior son el conjunto completo de controles ASCII. Este no es el caso de las plataformas EBCDIC; consulte “DIFERENCIAS DEL OPERADOR” en perlebcdic para una discusión completa de las diferencias entre estas para plataformas ASCII versus EBCDIC.

El uso de cualquier otro carácter siguiendo el "c" además de los enumerados anteriormente, se desaconseja, y a partir de Perl v5.20, los únicos caracteres realmente permitidos son los ASCII imprimibles, menos la llave izquierda "{". Lo que sucede con cualquiera de los otros caracteres permitidos es que el valor se deriva mediante xor’ing con el séptimo bit, que es 64, y se genera una advertencia si está habilitado. El uso de caracteres no permitidos genera un error fatal.

Para obtener controles independientes de la plataforma, puede usar N{...}.

[6]

El resultado es el carácter especificado por el número octal entre llaves. Ver “[8]”a continuación para obtener detalles sobre qué personaje.

Si se encuentra un carácter que no es un dígito octal, se genera una advertencia y el valor se basa en los dígitos octales anteriores, descartándolo y todos los caracteres siguientes hasta la llave de cierre. Es un error fatal si no hay dígitos octales.

[7]

El resultado es el carácter especificado por el número octal de tres dígitos en el rango de 000 a 777 (pero es mejor no usarlo por encima de 077, consulte el párrafo siguiente). Ver “[8]”a continuación para obtener detalles sobre qué personaje.

Algunos contextos permiten 2 o incluso 1 dígito, pero cualquier uso sin exactamente tres dígitos, siendo el primero un cero, puede dar resultados no deseados. (Por ejemplo, en una expresión regular puede confundirse con una referencia inversa; consulte “Escapes octales” en perlrebackslash.) A partir de Perl 5.14, puede usar o{} en cambio, lo que evita todos estos problemas. De lo contrario, es mejor usar esta construcción solo para ordinales 77 y abajo, recordando rellenar a la izquierda con ceros para hacer tres dígitos. Para ordinales más grandes, utilice o{}, o convertir a otra cosa, como hexadecimal y usar N{U+} (que es portátil entre plataformas con diferentes conjuntos de caracteres) o x{} en lugar de.

[8]

Varias construcciones anteriores especifican un carácter mediante un número. Ese número da la posición del carácter en la codificación del juego de caracteres (indexado desde 0). A esto se le llama como sinónimo ordinal, posición de código o punto de código. Perl funciona en plataformas que tienen una codificación nativa actualmente de ASCII / Latin1 o EBCDIC, cada una de las cuales permite la especificación de 256 caracteres. En general, si el número es 255 (0xFF, 0377) o menos, Perl lo interpreta en la codificación nativa de la plataforma. Si el número es 256 (0x100, 0400) o superior, Perl lo interpreta como un punto de código Unicode y el resultado es el carácter Unicode correspondiente. Por ejemplo x{50} y o{120} ambos son el número 80 en decimal, que es menor que 256, por lo que el número se interpreta en la codificación del juego de caracteres nativo. En ASCII, el carácter en la posición 80 (indexado desde 0) es la letra "P", y en EBCDIC es el símbolo comercial "&". x{100} y o{400} son 256 en decimal, por lo que el número se interpreta como un punto de código Unicode sin importar cuál sea la codificación nativa. El nombre del carácter en la posición 256 (indexado por 0) en Unicode es LATIN CAPITAL LETTER A WITH MACRON.

Una excepción a la regla anterior es que N{U+hex number} siempre se interpreta como un punto de código Unicode, de modo que N{U+0050} es "P" incluso en plataformas EBCDIC.

NOTA: A diferencia de C y otros lenguajes, Perl no tiene v secuencia de escape para la pestaña vertical (VT, que es 11 tanto en ASCII como en EBCDIC), pero puede usar N{VT}, ck, N{U+0b}, o x0b. (v tiene significado en los patrones de expresiones regulares en Perl, vea perlre.)

Las siguientes secuencias de escape están disponibles en construcciones que se interpolan, pero no en transliteraciones.

l          lowercase next character only
u          titlecase (not uppercase!) next character only
L          lowercase all characters till E or end of string
U          uppercase all characters till E or end of string
F          foldcase all characters till E or end of string
Q          quote (disable) pattern metacharacters till E or
            end of string
E          end either case modification or quoted section
            (whichever was last seen)

Consulte “quotemeta” en perlfunc para obtener la definición exacta de los caracteres citados por Q.

L, U, F, y Q se puede apilar, en cuyo caso necesita uno E para cada. Por ejemplo:

say"This Qquoting ubusiness Uhere isn't quiteE done yet,E is it?";
This quoting Business HERE ISN'T QUITE done yet, is it?

Si un use locale formulario que incluye LC_CTYPE está en efecto (ver perllocale), el mapa de casos utilizado por l, L, u, y U se toma de la configuración regional actual. Si Unicode (por ejemplo, N{} o puntos de código de 0x100 o más), el mapa de casos utilizado por l, L, u, y U es como lo define Unicode. Eso significa que el mapeo de mayúsculas y minúsculas de un solo carácter a veces puede producir una secuencia de varios caracteres. Debajo use locale, F produce los mismos resultados que L para todas las configuraciones regionales menos una UTF-8, donde en su lugar usa la definición Unicode.

Todos los sistemas utilizan el virtual "n" para representar un terminador de línea, llamado “nueva línea”. No existe tal cosa como un carácter de nueva línea física invariable. Es solo una ilusión que el sistema operativo, los controladores de dispositivos, las bibliotecas C y Perl conspiran para preservar. No todos los sistemas leen "r" como ASCII CR y "n" como ASCII LF. Por ejemplo, en los antiguos Macs (pre-MacOS X) de antaño, estos solían estar invertidos, y en los sistemas sin un terminador de línea, la impresión "n" podría no emitir datos reales. En general, utilice "n" cuando te refieres a una “nueva línea” para tu sistema, pero usa el ASCII literal cuando necesitas un carácter exacto. Por ejemplo, la mayoría de los protocolos de red esperan y prefieren un CR + LF ("1512" o "cMcJ") para terminadores de línea, y aunque a menudo aceptan "12", rara vez toleran solo "15". Si tiene el hábito de usar "n" para la creación de redes, puede que te quemen algún día.

Para las construcciones que se interpolan, las variables que comienzan con “$” o “@“se interpolan. Variables subindicadas como $a[3] o $href->{key}[0] también se interpolan, al igual que los sectores de matriz y hash. Pero llamadas a métodos como $obj->meth no son.

Al interpolar una matriz o un sector, se interpolan los elementos en orden, separados por el valor de $", por lo que es equivalente a interpolar join $", @array. Matrices de “puntuación” como @* generalmente se interpolan solo si el nombre está entre llaves @{*}, pero las matrices @_, @+, y @- se interpolan incluso sin llaves.

Para cadenas entre comillas dobles, la cita de Q se aplica después de la interpolación y se procesan los escapes.

"abcQfootbar$sExyz"

es equivalente a

"abc" . quotemeta("footbar$s") . "xyz"

Para el patrón de operadores de expresiones regulares (qr//, m// y s///), la cita de Q se aplica después de que se procesa la interpolación, pero antes de que se procesen los escapes. Esto permite que el patrón coincida literalmente (excepto por $ y @). Por ejemplo, las siguientes coincidencias:

'st' =~ /Qst/

Porque $ o @ desencadenar interpolación, necesitará usar algo como /QuserE@Qhost/ para emparejarlos literalmente.

Los patrones están sujetos a un nivel adicional de interpretación como expresión regular. Esto se hace como una segunda pasada, después de interpolar las variables, de modo que las expresiones regulares se puedan incorporar en el patrón a partir de las variables. Si esto no es lo que tu querer, usar Q para interpolar una variable literalmente.

Aparte del comportamiento descrito anteriormente, Perl no expande múltiples niveles de interpolación. En particular, contrariamente a las expectativas de los programadores de shell, las comillas inversas NO interpolar entre comillas dobles, ni las comillas simples impiden la evaluación de variables cuando se utilizan entre comillas dobles.

Operadores tipo cotización Regexp

A continuación, se muestran los operadores de tipo cotización que se aplican a la coincidencia de patrones y las actividades relacionadas.

qr/STRING/msixpodualn

Este operador cita (y posiblemente compila) su CUERDA como una expresión regular. CUERDA se interpola de la misma manera que PATRÓN en m/PATTERN/. Si "'" se utiliza como delimitador, no se realiza ninguna interpolación de variables. Devuelve un valor de Perl que se puede utilizar en lugar del correspondiente /STRING/msixpodualn expresión. El valor devuelto es una versión normalizada del patrón original. Mágicamente se diferencia de una cadena que contiene los mismos caracteres: ref(qr/x/) devuelve “Regexp”; sin embargo, la eliminación de referencias no está bien definida (actualmente obtiene la versión normalizada del patrón original, pero esto puede cambiar).

Por ejemplo,

$rex = qr/my.STRING/is;
print $rex;                 # prints (?si-xm:my.STRING)
s/$rex/foo/;

es equivalente a

s/my.STRING/foo/is;

El resultado puede usarse como un subpatrón en una coincidencia:

$re = qr/$pattern/;
$string =~ /foo${re}bar/;   # can be interpolated in other
                            # patterns
$string =~ $re;             # or used standalone
$string =~ /$re/;           # or this way

Dado que Perl puede compilar el patrón en el momento de la ejecución del qr() operador, usando qr() puede tener ventajas de velocidad en algunas situaciones, especialmente si el resultado de qr() se utiliza de forma independiente:

sub match {
    my $patterns = shift;
    my @compiled = map qr/$_/i, @$patterns;
    grep {
        my $success = 0;
        foreach my $pat (@compiled) {
            $success = 1, last if /$pat/;
        }
        $success;
    } @_;
}

Precompilación del patrón en una representación interna en el momento de qr() evita la necesidad de recompilar el patrón cada vez que una coincidencia /$pat/ se intenta. (Perl tiene muchas otras optimizaciones internas, pero ninguna se activaría en el ejemplo anterior si no usáramos qr() operador.)

Las opciones (especificadas por los siguientes modificadores) son:

m   Treat string as multiple lines.
s   Treat string as single line. (Make . match a newline)
i   Do case-insensitive pattern matching.
x   Use extended regular expressions; specifying two
    x's means t and the SPACE character are ignored within
    square-bracketed character classes
p   When matching preserve a copy of the matched string so
    that ${^PREMATCH}, ${^MATCH}, ${^POSTMATCH} will be
    defined (ignored starting in v5.20) as these are always
    defined starting in that release
o   Compile pattern only once.
a   ASCII-restrict: Use ASCII for d, s, w and [[:posix:]]
    character classes; specifying two a's adds the further
    restriction that no ASCII character will match a
    non-ASCII one under /i.
l   Use the current run-time locale's rules.
u   Use Unicode rules.
d   Use Unicode or native charset, as in 5.12 and earlier.
n   Non-capture mode. Don't let () fill in $1, $2, etc...

Si un patrón precompilado está incrustado en un patrón más grande, entonces el efecto de "msixpluadn" se propagará adecuadamente. El efecto que el /o modifier has no se propaga, estando restringido a aquellos patrones que lo usan explícitamente.

los /a, /d, /l, y /u Los modificadores (agregados en Perl 5.14) controlan las reglas del juego de caracteres, pero /a es el único que probablemente desee especificar explícitamente; los otros tres son seleccionados automáticamente por varios pragmas.

Consulte perlre para obtener información adicional sobre la sintaxis válida para CUERDAy para una mirada detallada a la semántica de las expresiones regulares. En particular, todos los modificadores excepto los obsoletos /o se explican con más detalle en “Modificadores” en perlre. /o se describe en la siguiente sección.

m/PATTERN/msixpodualngc
/PATTERN/msixpodualngc

Busca en una cadena una coincidencia de patrón y, en contexto escalar, devuelve verdadero si tiene éxito, falso si falla. Si no se especifica ninguna cadena a través del =~ o !~ operador, el $_ se busca la cadena. (La cadena especificada con =~ no es necesario que sea un lvalue; puede ser el resultado de una evaluación de expresión, pero recuerde =~ se une con bastante fuerza.) Véase también perlre.

Las opciones son las descritas en qr// encima; Además, están disponibles los siguientes modificadores del proceso de coincidencia:

g  Match globally, i.e., find all occurrences.
c  Do not reset search position on a failed match when /g is
   in effect.

Si "https://foroayuda.es/" es el delimitador, luego la inicial m es opcional. Con el m puede utilizar cualquier par de caracteres que no sean espacios en blanco (ASCII) como delimitadores. Esto es particularmente útil para hacer coincidir nombres de ruta que contienen "https://foroayuda.es/", para evitar LTS (síndrome del palillo inclinado). Si "?" es el delimitador, entonces se aplica una regla de coincidencia única, descrita en m?PATTERN? debajo. Si "'" (comillas simples) es el delimitador, no se realiza interpolación de variables en el PATRÓN. Cuando se utiliza un carácter delimitador válido en un identificador, se requieren espacios en blanco después de la m.

PATRÓN puede contener variables, que se interpolarán cada vez que se evalúe la búsqueda del patrón, excepto cuando el delimitador sea una comilla simple. (Tenga en cuenta que $(, $), y $| no se interpolan porque parecen pruebas de fin de cadena). Perl no recompilará el patrón a menos que cambie una variable interpolada que contiene. Puede obligar a Perl a omitir la prueba y nunca volver a compilar agregando un /o (que significa “una vez”) después del delimitador final. Érase una vez, Perl recompilaba expresiones regulares innecesariamente, y este modificador era útil para decirle que no lo hiciera, en aras de la velocidad. Pero ahora, las únicas razones para usar /o son uno de:

  1. Las variables tienen miles de caracteres y usted sabe que no cambian, y necesita exprimir el último pedacito de velocidad haciendo que Perl omita las pruebas para eso. (Hay una penalización de mantenimiento por hacer esto, como se menciona /o constituye una promesa de que no cambiará las variables en el patrón. Si los cambia, Perl ni siquiera lo notará).

  2. desea que el patrón utilice los valores iniciales de las variables independientemente de si cambian o no. (Pero hay formas más sensatas de lograr esto que usar /o.)

  3. Si el patrón contiene código incrustado, como

    use re 'eval';
    $code = 'foo(?{ $x })';
    /$code/

    entonces perl se recompilará cada vez, aunque la cadena del patrón no haya cambiado, para asegurar que el valor actual de $x se ve cada vez. Usar /o si quieres evitar esto.

La conclusión es que usar /o casi nunca es una buena idea.

El patrón vacío //

Si el PATRÓN evalúa la cadena vacía, la última exitosamente En su lugar, se utiliza una expresión regular coincidente. En este caso, solo el g y c se respetan las banderas en el patrón vacío; las otras banderas se toman del patrón original. Si ninguna coincidencia ha tenido éxito anteriormente, esto actuará (silenciosamente) en su lugar como un patrón vacío genuino (que siempre coincidirá).

Tenga en cuenta que es posible confundir a Perl para que piense // (la expresión regular vacía) es realmente // (el operador definido-or). Perl suele ser bastante bueno en esto, pero algunos casos patológicos pueden desencadenarlo, como $x/// (es eso ($x) / (//) o $x // /?) y print $fh // (print $fh(// o print($fh //?). En todos estos ejemplos, Perl asumirá que se refería a definido-o. Si se refería a la expresión regular vacía, simplemente use paréntesis o espacios para eliminar la ambigüedad, o incluso prefija la expresión regular vacía con una m (asi que // se convierte en m//).

Coincidencia en el contexto de la lista

Si el /g la opción no se usa, m// en el contexto de lista devuelve una lista que consta de subexpresiones emparejadas por los paréntesis en el patrón, es decir, ($1, $2, $3…) (Tenga en cuenta que aquí $1 etc.también están configurados). Cuando no hay paréntesis en el patrón, el valor de retorno es la lista (1) para el éxito. Con o sin paréntesis, se devuelve una lista vacía en caso de error.

Ejemplos:

open(TTY, "+</dev/tty")
   || die "can't access /dev/tty: $!";

<TTY> =~ /^y/i && foo();       # do foo if desired

if (/Version: *([0-9.]*)/) { $version = $1; }

next if m#^/usr/spool/uucp#;

# poor man's grep
$arg = shift;
while (<>) {
   print if /$arg/o; # compile only once (no longer needed!)
}

if (($F1, $F2, $Etc) = ($foo =~ /^(S+)s+(S+)s*(.*)/))

Este último ejemplo se divide $foo en las dos primeras palabras y el resto de la línea, y asigna esos tres campos a $F1, $F2, y $Etc. El condicional es verdadero si se asignaron variables; es decir, si el patrón coincide.

los /g El modificador especifica la coincidencia de patrones global, es decir, la coincidencia tantas veces como sea posible dentro de la cadena. Cómo se comporta depende del contexto. En el contexto de la lista, devuelve una lista de las subcadenas que coinciden con cualquier paréntesis de captura en la expresión regular. Si no hay paréntesis, devuelve una lista de todas las cadenas coincidentes, como si hubiera paréntesis alrededor de todo el patrón.

En contexto escalar, cada ejecución de m//g encuentra la siguiente coincidencia, devolviendo verdadero si coincide y falso si no hay más coincidencias. La posición después del último partido se puede leer o configurar usando el pos() función; ver “pos” en perlfunc. Una coincidencia fallida normalmente restablece la posición de búsqueda al comienzo de la cadena, pero puede evitarlo agregando el /c modificador (por ejemplo, m//gc). La modificación de la cadena de destino también restablece la posición de búsqueda.

G assertion

Puedes entremezclar m//g coincide con m/G.../g, dónde G es una aserción de ancho cero que coincide con la posición exacta donde la anterior m//g, si alguno, lo dejó. Sin el /g modificador, el G afirmación todavía se ancla en pos() como estaba al comienzo de la operación (ver “pos” en perlfunc), pero la coincidencia, por supuesto, solo se intenta una vez. Utilizando G sin /g en una cadena de destino que no ha tenido previamente un /g coincidencia que se le aplica es lo mismo que usar el A aserción para que coincida con el comienzo de la cadena. Tenga en cuenta también que, actualmente, G solo se apoya correctamente cuando se ancla al principio del patrón.

Ejemplos:

# list context
($one,$five,$fifteen) = (`uptime` =~ /(d+.d+)/g);

# scalar context
local $/ = "";
while ($paragraph = <>) {
    while ($paragraph =~ /p{Ll}['")]*[.!?]+['")]*s/g) {
        $sentences++;
    }
}
say $sentences;

Aquí hay otra forma de verificar las oraciones en un párrafo:

my $sentence_rx = qr{
   (?: (?<= ^ ) | (?<= s ) )  # after start-of-string or
                               # whitespace
   p{Lu}                      # capital letter
   .*?                         # a bunch of anything
   (?<= S )                   # that ends in non-
                               # whitespace
   (?<! b [DMS]r  )           # but isn't a common abbr.
   (?<! b Mrs )
   (?<! b Sra )
   (?<! b St  )
   [.?!]                       # followed by a sentence
                               # ender
   (?= $ | s )                # in front of end-of-string
                               # or whitespace
}sx;
local $/ = "";
while (my $paragraph = <>) {
   say "NEW PARAGRAPH";
   my $count = 0;
   while ($paragraph =~ /($sentence_rx)/g) {
       printf "tgot sentence %d: <%s>n", ++$count, $1;
   }
}

He aquí cómo usar m//gc con G:

$_ = "ppooqppqq";
while ($i++ < 2) {
    print "1: '";
    print $1 while /(o)/gc; print "', pos=", pos, "n";
    print "2: '";
    print $1 if /G(q)/gc;  print "', pos=", pos, "n";
    print "3: '";
    print $1 while /(p)/gc; print "', pos=", pos, "n";
}
print "Final: '$1', pos=",pos,"n" if /G(.)/;

El último ejemplo debería imprimirse:

1: 'oo', pos=4
2: 'q', pos=5
3: 'pp', pos=7
1: '', pos=7
2: 'q', pos=8
3: '', pos=8
Final: 'q', pos=8

Observe que el partido final coincidió q en lugar de p, que un partido sin el G ancla habría hecho. También tenga en cuenta que el partido final no se actualizó pos. pos solo se actualiza en un /g fósforo. Si el partido final realmente coincidió p, es una buena apuesta que esté ejecutando una versión antigua (anterior a 5.6.0) de Perl.

Un modismo útil para lex-como los escáneres es /G.../gc. Puede combinar varias expresiones regulares como esta para procesar una cadena parte por parte, realizando diferentes acciones según la expresión regular que coincida. Cada expresión regular intenta coincidir donde termina la anterior.

$_ = <<'EOL';
   $url = URI::URL->new( "http://example.com/" );
   die if $url eq "xXx";
EOL

LOOP: {
    print(" digits"),       redo LOOP if /Gd+b[,.;]?s*/gc;
    print(" lowercase"),    redo LOOP
                                   if /Gp{Ll}+b[,.;]?s*/gc;
    print(" UPPERCASE"),    redo LOOP
                                   if /Gp{Lu}+b[,.;]?s*/gc;
    print(" Capitalized"),  redo LOOP
                             if /Gp{Lu}p{Ll}+b[,.;]?s*/gc;
    print(" MiXeD"),        redo LOOP if /GpL+b[,.;]?s*/gc;
    print(" alphanumeric"), redo LOOP
                           if /G[p{Alpha}pN]+b[,.;]?s*/gc;
    print(" line-noise"),   redo LOOP if /GW+/gc;
    print ". That's all!n";
}

Aquí está la salida (dividida en varias líneas):

line-noise lowercase line-noise UPPERCASE line-noise UPPERCASE
line-noise lowercase line-noise lowercase line-noise lowercase
lowercase line-noise lowercase lowercase line-noise lowercase
lowercase line-noise MiXeD line-noise. That's all!
m?PATTERN?msixpodualngc

Esto es como el m/PATTERN/ búsqueda, excepto que solo coincide una vez entre las llamadas al reset() operador. Esta es una optimización útil cuando desea ver solo la primera aparición de algo en cada archivo de un conjunto de archivos, por ejemplo. Solamente m?? los patrones locales del paquete actual se restablecen.

while (<>) {
    if (m?^$?) {
                        # blank line between header and body
    }
} continue {
    reset if eof;       # clear m?? status for next file
}

Otro ejemplo cambió la primera codificación “latin1” que encuentra a “utf8” en un archivo de pod:

s//utf8/ if m? ^ =encoding h+ K latin1 ?x;

El comportamiento de coincidencia única está controlado por el delimitador de coincidencia que se ?; con cualquier otro delimitador este es el normal m// operador.

En el pasado, el líder m en m?PATTERN? era opcional, pero omitirlo produciría una advertencia de obsolescencia. A partir de la versión 5.22.0, omitirlo produce un error de sintaxis. Si encuentra esta construcción en un código anterior, simplemente puede agregar m.

s/PATTERN/REPLACEMENT/msixpodualngcer

Busca un patrón en una cadena y, si lo encuentra, reemplaza ese patrón con el texto de reemplazo y devuelve el número de sustituciones realizadas. De lo contrario, devuelve falso (un valor que es a la vez una cadena vacía ("") y cero numérico (0) como se describe en “Operadores relacionales”).

Si el /r Se utiliza la opción (no destructiva), luego ejecuta la sustitución en una copia de la cadena y, en lugar de devolver el número de sustituciones, devuelve la copia independientemente de que haya ocurrido una sustitución. La cadena original nunca se cambia cuando /r se utiliza. La copia siempre será una cadena simple, incluso si la entrada es un objeto o una variable vinculada.

Si no se especifica ninguna cadena a través del =~ o !~ operador, el $_ se busca y modifica la variable. A menos que el /r se utiliza la opción, la cadena especificada debe ser una variable escalar, un elemento de matriz, un elemento hash o una asignación a uno de esos; es decir, algún tipo de lvalor escalar.

Si el delimitador elegido es una comilla simple, no se realiza ninguna interpolación de variable en el PATRÓN o la REEMPLAZO. De lo contrario, si el PATRÓN contiene una $ que parece una variable en lugar de una prueba de fin de cadena, la variable se interpolará en el patrón en tiempo de ejecución. Si desea que el patrón se compile solo una vez la primera vez que se interpola la variable, use el /o opción. Si el patrón se evalúa como una cadena vacía, en su lugar se usa la última expresión regular ejecutada con éxito. Consulte perlre para obtener más explicaciones sobre estos.

Las opciones son como con m// con la adición de las siguientes opciones específicas de reemplazo:

e   Evaluate the right side as an expression.
ee  Evaluate the right side as a string then eval the
    result.
r   Return substitution and leave the original string
    untouched.

Cualquier delimitador que no sea un espacio en blanco puede reemplazar las barras. Agregue espacio después del s cuando se usa un carácter permitido en identificadores. Si se utilizan comillas simples, no se realiza ninguna interpretación en la cadena de reemplazo (la /e Sin embargo, el modificador anula esto). Tenga en cuenta que Perl trata las comillas inversas como delimitadores normales; el texto de reemplazo no se evalúa como un comando. Si el PATRÓN está delimitado por comillas entre corchetes, el REEMPLAZO tiene su propio par de comillas, que pueden estar entre corchetes o no, por ejemplo, s(foo)(bar) o s<foo>/bar/. A /e hará que la parte de reemplazo se trate como una expresión Perl completa y se evalúe en ese mismo momento. Sin embargo, se verifica la sintaxis en tiempo de compilación. Un segundo e El modificador hará que la parte de reemplazo sea evaled antes de ejecutarse como una expresión de Perl.

Ejemplos:

s/bgreenb/mauve/g;              # don't change wintergreen

$path =~ s|/usr/bin|/usr/local/bin|;

s/Login: $foo/Login: $bar/; # run-time pattern

($foo = $bar) =~ s/this/that/;      # copy first, then
                                    # change
($foo = "$bar") =~ s/this/that/;    # convert to string,
                                    # copy, then change
$foo = $bar =~ s/this/that/r;       # Same as above using /r
$foo = $bar =~ s/this/that/r
            =~ s/that/the other/r;  # Chained substitutes
                                    # using /r
@foo = map { s/this/that/r } @bar   # /r is very useful in
                                    # maps

$count = ($paragraph =~ s/Misterb/Mr./g);  # get change-cnt

$_ = 'abc123xyz';
s/d+/$&*2/e;               # yields 'abc246xyz'
s/d+/sprintf("%5d",$&)/e;  # yields 'abc  246xyz'
s/w/$& x 2/eg;             # yields 'aabbcc  224466xxyyzz'

s/%(.)/$percent{$1}/g;      # change percent escapes; no /e
s/%(.)/$percent{$1} || $&/ge;       # expr now, so /e
s/^=(w+)/pod($1)/ge;       # use function call

$_ = 'abc123xyz';
$x = s/abc/def/r;           # $x is 'def123xyz' and
                            # $_ remains 'abc123xyz'.

# expand variables in $_, but dynamics only, using
# symbolic dereferencing
s/$(w+)/${$1}/g;

# Add one to the value of any numbers in the string
s/(d+)/1 + $1/eg;

# Titlecase words in the last 30 characters only
substr($str, -30) =~ s/b(p{Alpha}+)b/uL$1/g;

# This will expand any embedded scalar variable
# (including lexicals) in $_ : First $1 is interpolated
# to the variable name, and then evaluated
s/($w+)/$1/eeg;

# Delete (most) C comments.
$program =~ s {
    /*     # Match the opening delimiter.
    .*?     # Match a minimal number of characters.
    */     # Match the closing delimiter.
} []gsx;

s/^s*(.*?)s*$/$1/;        # trim whitespace in $_,
                            # expensively

for ($variable) {           # trim whitespace in $variable,
                            # cheap
    s/^s+//;
    s/s+$//;
}

s/([^ ]*) *([^ ]*)/$2 $1/;  # reverse 1st two fields

$foo !~ s/A/a/g;    # Lowercase all A's in $foo; return
                    # 0 if any were found and changed;
                    # otherwise return 1

Tenga en cuenta el uso de $ en lugar de en el último ejemplo. diferente a sed, usamos el dígito> forma sólo en el lado izquierdo. En cualquier otro lugar es $dígito>.

Ocasionalmente, no puede usar solo un /g para que se produzcan todos los cambios que desee. A continuación, se muestran dos casos habituales:

# put commas in the right places in an integer
1 while s/(d)(ddd)(?!d)/$1,$2/g;

# expand tabs to 8-column spacing
1 while s/t+/' ' x (length($&)*8 - length($`)%8)/e;

Tiempo s/// acepta el /c , no tiene ningún efecto más allá de producir una advertencia si las advertencias están habilitadas.

Operadores similares a cotizaciones

q/STRING/
'STRING'

Una cadena literal entre comillas simples. Una barra invertida representa una barra invertida a menos que esté seguida por el delimitador u otra barra invertida, en cuyo caso se interpola el delimitador o la barra invertida.

$foo = q!I said, "You said, 'She said it.'"!;
$bar = q('This is it.');
$baz = 'n';                # a two-character string
qq/STRING/
"STRING"

Una cadena interpolada entre comillas dobles.

$_ .= qq
 (*** The previous line contains the naughty word "$1".n)
            if /b(tcl|java|python)b/i;      # 🙂
$baz = "n";                # a one-character string
qx/STRING/
`STRING`

Una cadena que (posiblemente) se interpola y luego se ejecuta como un comando del sistema, a través de / bin / sh o su equivalente si es necesario. Se respetarán los comodines, las canalizaciones y las redirecciones de Shell. similar a system, si la cadena no contiene metacaracteres de shell, se ejecutará directamente. Se devuelve la salida estándar recopilada del comando; el error estándar no se ve afectado. En contexto escalar, vuelve como una sola cadena (potencialmente multilínea), o undef si el shell (o comando) no se pudo iniciar. En el contexto de la lista, devuelve una lista de líneas (sin embargo, ha definido líneas con $/ o $INPUT_RECORD_SEPARATOR), o una lista vacía si el shell (o comando) no se pudo iniciar.

Debido a que las comillas invertidas no afectan el error estándar, use la sintaxis del descriptor de archivos de shell (suponiendo que el shell lo admita) si desea abordar esto. Para capturar STDERR y STDOUT de un comando juntos:

$output = `cmd 2>&1`;

Para capturar el STDOUT de un comando pero descartar su STDERR:

$output = `cmd 2>/dev/null`;

Para capturar el STDERR de un comando pero descartar su STDOUT (el orden es importante aquí):

$output = `cmd 2>&1 1>/dev/null`;

Para intercambiar STDOUT y STDERR de un comando para capturar el STDERR pero dejar su STDOUT para que salga el STDERR antiguo:

$output = `cmd 3>&1 1>&2 2>&3 3>&-`;

Para leer tanto el STDOUT como el STDERR de un comando por separado, es más fácil redirigirlos por separado a archivos y luego leerlos cuando el programa haya terminado:

system("program args 1>program.stdout 2>program.stderr");

El identificador de archivo STDIN utilizado por el comando se hereda del STDIN de Perl. Por ejemplo:

open(SPLAT, "stuff")   || die "can't open stuff: $!";
open(STDIN, "<&SPLAT") || die "can't dupe SPLAT: $!";
print STDOUT `sort`;

imprimirá el contenido ordenado del archivo llamado “cosas”.

El uso de comillas simples como delimitador protege el comando de la interpolación de comillas dobles de Perl, pasándolo al shell en su lugar:

$perl_info  = qx(ps $$);            # that's Perl's $$
$shell_info = qx'ps $$';            # that's the new shell's $$

La forma en que se evalúa esa cadena está totalmente sujeta al intérprete de comandos de su sistema. En la mayoría de las plataformas, tendrá que proteger los metacaracteres de shell si desea que se traten literalmente. En la práctica, esto es difícil de hacer, ya que no está claro cómo escapar de qué personajes. Consulte perlsec para obtener un ejemplo limpio y seguro de un manual fork() y exec() para emular las comillas invertidas de forma segura.

En algunas plataformas (en particular, las similares a DOS), es posible que el shell no sea capaz de manejar comandos de varias líneas, por lo que es posible que poner nuevas líneas en la cadena no le proporcione lo que desea. Es posible que pueda evaluar varios comandos en una sola línea separándolos con el carácter separador de comandos, si su shell lo admite (por ejemplo, ; en muchos shells de Unix y & en Windows NT cmd cascarón).

Perl intentará vaciar todos los archivos abiertos para la salida antes de iniciar el proceso hijo, pero es posible que esto no sea compatible con algunas plataformas (ver perlport). Para estar seguro, es posible que deba configurar $| ($AUTOFLUSH en English) o llame al autoflush() método de IO::Handle en cualquier manija abierta.

Tenga en cuenta que algunos shells de comandos pueden imponer restricciones a la longitud de la línea de comandos. Debe asegurarse de que sus cadenas no excedan este límite después de las interpolaciones necesarias. Consulte las notas de la versión específicas de la plataforma para obtener más detalles sobre su entorno particular.

El uso de este operador puede conducir a programas que son difíciles de portar, porque los comandos de shell llamados varían entre sistemas y, de hecho, pueden no estar presentes en absoluto. Como un ejemplo, el type comando bajo el shell POSIX es muy diferente del type comando en DOS. Eso no significa que deba hacer todo lo posible para evitar las comillas inversas cuando son la forma correcta de hacer algo. Perl fue creado para ser un lenguaje adhesivo, y una de las cosas que une son los comandos. Solo entiende en lo que te estás metiendo.

Igual que system, las comillas invertidas ponen el código de salida del proceso hijo en $?. Si desea inspeccionar manualmente la falla, puede verificar todos los posibles modos de falla inspeccionando $? como esto:

if ($? == -1) {
    print "failed to execute: $!n";
}
elsif ($? & 127) {
    printf "child died with signal %d, %s coredumpn",
        ($? & 127),  ($? & 128) ? 'with' : 'without';
}
else {
    printf "child exited with value %dn", $? >> 8;
}

Utilice el pragma abierto para controlar las capas de E / S utilizadas al leer la salida del comando, por ejemplo:

use open IN => ":encoding(UTF-8)";
my $x = `cmd-producing-utf-8`;

qx// también se puede llamar como una función con “readpipe” en perlfunc.

Consulte “Operadores de E / S” para obtener más información.

qw/STRING/

Evalúa a una lista de las palabras extraídas de CUERDA, utilizando espacios en blanco incrustados como delimitadores de palabras. Puede entenderse como equivalente aproximadamente a:

split(" ", q/STRING/);

las diferencias son que solo se divide en espacios en blanco ASCII, genera una lista real en tiempo de compilación y, en contexto escalar, devuelve el último elemento de la lista. Entonces esta expresión:

qw(foo bar baz)

es semánticamente equivalente a la lista:

"foo", "bar", "baz"

Algunos ejemplos que se ven con frecuencia:

use POSIX qw( setlocale localeconv )
@EXPORT = qw( foo bar baz );

Un error común es tratar de separar las palabras con comas o poner comentarios en varias líneas. qw-cuerda. Por esta razón, la use warnings pragma y el -w interruptor (es decir, el $^W variable) produce advertencias si el CUERDA contiene la "," o la "#" personaje.

tr/SEARCHLIST/REPLACEMENTLIST/cdsr
y/SEARCHLIST/REPLACEMENTLIST/cdsr

Translitera todas las apariciones de los caracteres encontrados (o no encontrados si el /c se especifica el modificador) en la lista de búsqueda con el carácter posicionalmente correspondiente en la lista de reemplazo, posiblemente eliminando algunos, dependiendo de los modificadores especificados. Devuelve el número de caracteres reemplazados o eliminados. Si no se especifica ninguna cadena a través del =~ o !~ operador, el $_ la cadena está transliterada.

Para sed devotos y se proporciona como sinónimo de tr.

Si el /r La opción (no destructiva) está presente, se realiza una nueva copia de la cadena y se transliteran sus caracteres, y esta copia se devuelve sin importar si se modificó o no: la cadena original siempre se deja sin cambios. La nueva copia es siempre una cadena simple, incluso si el La cadena de entrada es un objeto o una variable vinculada.

A menos que el /r se utiliza la opción, la cadena especificada con =~ debe ser una variable escalar, un elemento de matriz, un elemento hash o una asignación a uno de esos; en otras palabras, un lvalue.

Si los caracteres que delimitan LISTA DE BÚSQUEDA y LISTA DE REEMPLAZO son comillas simplestr'SEARCHLIST'REPLACEMENTLIST'), la única interpolación es la eliminación de de pares de \.

De lo contrario, se puede especificar un rango de caracteres con un guión, por lo que tr/A-J/0-9/ hace el mismo reemplazo que tr/ACEGIBDFHJ/0246813579/.

Si el LISTA DE BÚSQUEDA está delimitado por comillas entre corchetes, el LISTA DE REEMPLAZO debe tener su propio par de comillas, que pueden estar entre corchetes o no; por ejemplo, tr[aeiouy][yuoiea] o tr(+-*/)/ABCD/.

Los caracteres pueden ser literales o (si los delimitadores no son comillas simples) cualquiera de las secuencias de escape aceptadas en cadenas entre comillas dobles. Pero nunca hay una interpolación variable, por lo que "$" y "@" siempre se tratan como literales. Un guión al principio o al final, o precedido por una barra invertida, también se considera siempre literal. Los detalles de la secuencia de escape se encuentran en la tabla cerca del comienzo de esta sección.

Tenga en cuenta que tr lo hace no hacer clases de caracteres de expresión regular como d o pL. los tr operador no es equivalente al tr(1) utilidad. tr[a-z][A-Z] pondrá en mayúsculas las 26 letras de la “a” a la “z”, pero para el cambio de mayúsculas y minúsculas no se limita a ASCII, utilice lc, uc, lcfirst, ucfirst (todo documentado en perlfunc), o el operador de sustitución s/PATTERN/REPLACEMENT/ (con U, u, L, y l la interpolación de cadenas se escapa en el REEMPLAZO parte).

La mayoría de los rangos no son portátiles entre conjuntos de caracteres, pero algunos indican a Perl que realice un manejo especial para hacerlos portátiles. Hay dos clases de cocinas portátiles. Los primeros son los subconjuntos de los rangos. A-Z, a-z, y 0-9, cuando se expresa como caracteres literales.

tr/h-k/H-K/

pone en mayúscula las letras "h", "i", "j", y "k" y nada más, sin importar cuál sea el conjunto de caracteres de la plataforma. En contraste, todos

tr/x68-x6B/x48-x4B/
tr/h-x6B/H-x4B/
tr/x68-k/x48-K/

hacen las mismas mayúsculas que en el ejemplo anterior cuando se ejecutan en plataformas ASCII, pero algo completamente diferente en las EBCDIC.

La segunda clase de rangos portátiles se invoca cuando uno o ambos puntos finales del rango se expresan como N{...}

$string =~ tr/N{U+20}-N{U+7E}//d;

quita de $string todos los caracteres de la plataforma que sean equivalentes a cualquiera de Unicode U + 0020, U + 0021, … U + 007D, U + 007E. Esta es una gama portátil y tiene el mismo efecto en todas las plataformas en las que se ejecuta. En este ejemplo, estos son los caracteres imprimibles ASCII. Entonces, después de ejecutar esto, $string solo tiene controles y caracteres que no tienen equivalentes ASCII.

Pero, incluso para las cocinas portátiles, generalmente no es obvio lo que se incluye sin tener que buscar cosas en el manual. Un principio sólido es usar solo rangos que comiencen y terminen en cualquier alfabeto ASCII de igual caso (b-e, B-E) o dígitos (1-4). Cualquier otra cosa no está clara (e intransferible a menos que N{...} se utiliza). En caso de duda, deletree el conjunto de caracteres en su totalidad.

Opciones:

c   Complement the SEARCHLIST.
d   Delete found but unreplaced characters.
r   Return the modified string and leave the original string
    untouched.
s   Squash duplicate replaced characters.

Si el /d se especifica el modificador, cualquier carácter especificado por LISTA DE BÚSQUEDA no encontrado en LISTA DE REEMPLAZO se eliminan. (Tenga en cuenta que esto es un poco más flexible que el comportamiento de algunos tr programas, que eliminan todo lo que encuentran en el LISTA DE BÚSQUEDA, período.)

Si el /s se especifica el modificador, las secuencias de caracteres, todos en una fila, que se transliteraron al mismo carácter se reducen a una sola instancia de ese carácter.

my $a = "aaaba"
$a =~ tr/a/a/s     # $a now is "aba"

Si el /d se utiliza el modificador, el LISTA DE REEMPLAZO siempre se interpreta exactamente como se especifica. De lo contrario, si el LISTA DE REEMPLAZO es más corto que el LISTA DE BÚSQUEDA, el carácter final, si lo hay, se replica hasta que sea lo suficientemente largo. No habrá un personaje final si y solo si el LISTA DE REEMPLAZO está vacío, en cuyo caso LISTA DE REEMPLAZO es copiado de LISTA DE BÚSQUEDA. Un vacío LISTA DE REEMPLAZO es útil para contar caracteres en una clase o para aplastar secuencias de caracteres en una clase.

tr/abcd//            tr/abcd/abcd/
tr/abcd/AB/          tr/abcd/ABBB/
tr/abcd//d           s/[abcd]//g
tr/abcd/AB/d         (tr/ab/AB/ + s/[cd]//g)  - but run together

Si el /c se especifica el modificador, los caracteres a transliterar son los que NO están en LISTA DE BÚSQUEDA, es decir, se complementa. Si /d y / o /s también se especifican, se aplican a los complementados LISTA DE BÚSQUEDA. Recuerde, que si LISTA DE REEMPLAZO está vacío (excepto debajo /d) una copia de LISTA DE BÚSQUEDA se utiliza en su lugar. Esa copia se realiza después de complementar bajo /c. LISTA DE BÚSQUEDA se ordena por orden de puntos de código después de complementar, y cualquier LISTA DE REEMPLAZO se aplica a ese resultado ordenado. Esto significa que bajo /c, el orden de los caracteres especificado en LISTA DE BÚSQUEDA es irrelevante. Esto puede llevar a resultados diferentes en los sistemas EBCDIC si LISTA DE REEMPLAZO contiene más de un carácter, por lo que generalmente no es portátil de usar /c con tal LISTA DE REEMPLAZO.

Otra forma de describir la operación es esta: Si /c se especifica, el LISTA DE BÚSQUEDA se ordena por orden de puntos de código y luego se complementa. Si LISTA DE REEMPLAZO está vacío y /d no está especificado, LISTA DE REEMPLAZO es reemplazado por una copia de LISTA DE BÚSQUEDA (modificado en /c), y estas listas potencialmente modificadas se utilizan como base para lo que sigue. Cualquier carácter de la cadena de destino que no esté en LISTA DE BÚSQUEDA pasa sin cambios. Todos los demás caracteres de la cadena de destino se reemplazan por el carácter de LISTA DE REEMPLAZO que posicionalmente corresponde a su pareja en LISTA DE BÚSQUEDA, excepto que bajo /s, el segundo y los siguientes caracteres se exprimen en una secuencia de caracteres en una fila que se traducen todos al mismo carácter. Si LISTA DE BÚSQUEDA es más largo que LISTA DE REEMPLAZO, caracteres en la cadena de destino que coinciden con un carácter en LISTA DE BÚSQUEDA que no tiene correspondencia en LISTA DE REEMPLAZO se eliminan de la cadena de destino si /d está especificado; o reemplazado por el carácter final en LISTA DE REEMPLAZO si /d no se especifica.

Algunos ejemplos:

$ARGV[1] =~ tr/A-Z/a-z/;   # canonicalize to lower case ASCII

$cnt = tr/*/*/;            # count the stars in $_
$cnt = tr/*//;             # same thing

$cnt = $sky =~ tr/*/*/;    # count the stars in $sky
$cnt = $sky =~ tr/*//;     # same thing

$cnt = $sky =~ tr/*//c;    # count all the non-stars in $sky
$cnt = $sky =~ tr/*/*/c;   # same, but transliterate each non-star
                           # into a star, leaving the already-stars
                           # alone.  Afterwards, everything in $sky
                           # is a star.

$cnt = tr/0-9//;           # count the ASCII digits in $_

tr/a-zA-Z//s;              # bookkeeper -> bokeper
tr/o/o/s;                  # bookkeeper -> bokkeeper
tr/oe/oe/s;                # bookkeeper -> bokkeper
tr/oe//s;                  # bookkeeper -> bokkeper
tr/oe/o/s;                 # bookkeeper -> bokkopor

($HOST = $host) =~ tr/a-z/A-Z/;
 $HOST = $host  =~ tr/a-z/A-Z/r; # same thing

$HOST = $host =~ tr/a-z/A-Z/r   # chained with s///r
              =~ s/:/ -p/r;

tr/a-zA-Z/ /cs;                 # change non-alphas to single space

@stripped = map tr/a-zA-Z/ /csr, @original;
                                # /r with map

tr [200-377]
   [00-177];                 # wickedly delete 8th bit

$foo !~ tr/A/a/    # transliterate all the A's in $foo to 'a',
                   # return 0 if any were found and changed.
                   # Otherwise return 1

Si se dan varias transliteraciones para un carácter, solo se usa la primera:

tr/AAA/XYZ/

transliterará cualquier A a X.

Debido a que la tabla de transliteración se crea en tiempo de compilación, ni LISTA DE BÚSQUEDA ni el LISTA DE REEMPLAZO están sujetos a interpolación de comillas dobles. Eso significa que si desea utilizar variables, debe utilizar un eval():

eval "tr/$oldlist/$newlist/";
die [email protected] if [email protected];

eval "tr/$oldlist/$newlist/, 1" or die [email protected];
<<EOF

Una forma de cotización orientada a líneas se basa en la sintaxis de shell “here-document”. Siguiendo un << usted especifica una cadena para terminar el material citado, y todas las líneas que siguen a la línea actual hasta la cadena de terminación son el valor del artículo.

Prefijando la cadena de terminación con un ~ especifica que desea utilizar “Documentos aquí con sangría” (ver más abajo).

La cadena de terminación puede ser un identificador (una palabra) o algún texto entre comillas. Un identificador sin comillas funciona como comillas dobles. Puede que no haya un espacio entre el << y el identificador, a menos que el identificador se cite explícitamente. La cadena de terminación debe aparecer sola (sin comillas y sin espacios en blanco circundantes) en la línea de terminación.

Si se cita la cadena de terminación, el tipo de comillas utilizado determina el tratamiento del texto.

Doble comillas

Las comillas dobles indican que el texto se interpolará utilizando exactamente las mismas reglas que las cadenas de comillas dobles normales.

   print <<EOF;
The price is $Price.
EOF

   print << "EOF"; # same as above
The price is $Price.
EOF
Comillas simples

Las comillas simples indican que el texto debe tratarse literalmente sin interpolar su contenido. Esto es similar a las cadenas entre comillas simples, excepto que las barras invertidas no tienen un significado especial, con \ siendo tratados como dos barras invertidas y no como una como lo harían en cualquier otro constructo de citas.

Al igual que en el caparazón, una espada invertida siguiendo el << significa lo mismo que una cadena entre comillas simples:

    $cost = <<'VISTA';  # hasta la ...
That'll be $10 please, ma'am.
VISTA

    $cost = <<VISTA;   # Same thing!
That'll be $10 please, ma'am.
VISTA

Esta es la única forma de citar en Perl en la que no hay necesidad de preocuparse por escapar del contenido, algo que los generadores de código pueden hacer un buen uso.

Backticks

El contenido del documento here se trata como si la cadena estuviera incrustada entre comillas invertidas. Por lo tanto, el contenido se interpola como si estuviera entre comillas dobles y luego se ejecuta a través del shell, con los resultados de la ejecución devueltos.

   print << `EOC`; # execute command and get results
echo hi there
EOC
Here-docs con sangría

El modificador here-doc ~ le permite sangrar sus here-docs para hacer que el código sea más legible:

if ($some_var) {
  print <<~EOF;
    This is a here-doc
    EOF
}

Esto imprimirá …

This is a here-doc

… sin espacios en blanco iniciales.

El delimitador se utiliza para determinar el exacto espacios en blanco para eliminar del principio de cada línea. Todas las lineas debe tener al menos el mismo espacio en blanco inicial (excepto las líneas que solo contienen una nueva línea) o perl croará. Las pestañas y los espacios se pueden mezclar, pero se combinan exactamente. ¡Una pestaña no será igual a 8 espacios!

Se conservarán espacios en blanco iniciales adicionales (más allá de lo que precedió al delimitador):

print <<~EOF;
  This text is not indented
    This text is indented with two spaces
            This text is indented with two tabs
  EOF

Finalmente, el modificador se puede usar con todas las formas mencionadas anteriormente:

<<~EOF;
<<~'EOF'
<<~"EOF"
<<~`EOF`

Y se pueden utilizar espacios en blanco entre ~ y delimitadores entre comillas:

<<~ 'EOF'; # ... "EOF", `EOF`

Es posible apilar varios here-docs seguidos:

   print <<"foo", <<"bar"; # you can stack them
I said foo.
foo
I said bar.
bar

   myfunc(<< "THIS", 23, <<'THAT');
Here's a line
or two.
THIS
and here's another.
THAT

Solo no olvide que debe poner un punto y coma al final para terminar la declaración, ya que Perl no sabe que no va a intentar hacer esto:

   print <<ABC
179231
ABC
   + 20;

Si desea eliminar el terminador de línea de sus here-docs, use chomp().

chomp($string = <<'END');
This is a string.
END

Si desea que sus here-docs estén sangrados con el resto del código, use el <<~FOO construcción descrita en “Documentos aquí con sangría”:

$quote = <<~'FINIS';
   The Road goes ever on and on,
   down from the door where it began.
   FINIS

Si usa un documento aquí dentro de una construcción delimitada, como en s///eg, el material citado debe seguir apareciendo en la línea siguiente a la <<FOO marcador, lo que significa que puede estar dentro de la construcción delimitada:

s/this/<<E . 'that'
the other
E
 . 'more '/eg;

Funciona de esta manera a partir de Perl 5.18. Históricamente, fue inconsistente y tendrías que escribir

s/this/<<E . 'that'
 . 'more '/eg;
the other
E

fuera de las evaluaciones de cadena.

Además, las reglas de cotización para el identificador de fin de cadena no están relacionadas con las reglas de cotización de Perl. q(), qq(), y similares no se admiten en lugar de '' y "", y la única interpolación es para la barra invertida del carácter de cita:

print << "abc"def";
testing...
abc"def

Finalmente, las cadenas entre comillas no pueden abarcar varias líneas. La regla general es que el identificador debe ser una cadena literal. Quédese con eso, y debería estar seguro.

Detalles sangrientos del análisis sintáctico de construcciones entre comillas

Cuando se le presenta algo que puede tener varias interpretaciones diferentes, Perl usa la DWIM (ese es el principio “Haz lo que quiero decir”) para elegir la interpretación más probable. Esta estrategia tiene tanto éxito que los programadores de Perl a menudo no sospechan la ambivalencia de lo que escriben. Pero de vez en cuando, las nociones de Perl difieren sustancialmente de lo que el autor quiso decir honestamente.

Esta sección espera aclarar cómo Perl maneja las construcciones entre comillas. Aunque la razón más común para aprender esto es desentrañar expresiones regulares laberínticas, debido a que los pasos iniciales del análisis son los mismos para todos los operadores de comillas, todos se analizan juntos.

La regla de análisis sintáctica de Perl más importante es la primera que se analiza a continuación: cuando se procesa una construcción entre comillas, Perl primero encuentra el final de esa construcción y luego interpreta su contenido. Si comprende esta regla, puede omitir el resto de esta sección en la primera lectura. Es probable que las otras reglas contradigan las expectativas del usuario con mucha menos frecuencia que esta primera.

Algunos pases que se analizan a continuación se realizan al mismo tiempo, pero debido a que sus resultados son los mismos, los consideramos individualmente. Para diferentes construcciones de citas, Perl realiza diferentes números de pasadas, de uno a cuatro, pero estas pasadas siempre se realizan en el mismo orden.

Encontrar el final

El primer paso es encontrar el final del constructo citado. Esto da como resultado que se guarde en una ubicación segura una copia del texto (entre los delimitadores inicial y final), normalizado según sea necesario para evitar la necesidad de saber cuáles eran los delimitadores originales.

Si la construcción es un documento aquí, el delimitador final es una línea que tiene una cadena final como contenido. Por lo tanto <<EOF es terminado por EOF seguido inmediatamente por "n" y comenzando desde la primera columna de la línea de terminación. Al buscar la línea final de un here-doc, no se omite nada. En otras palabras, las líneas después de la sintaxis here-doc se comparan con la cadena de terminación línea por línea.

Para las construcciones, excepto here-docs, se utilizan caracteres individuales como delimitadores de inicio y finalización. Si el delimitador inicial es una puntuación inicial (es decir (, [, {, or <), the ending delimiter is the corresponding closing punctuation (that is ), ], }, o >). Si el delimitador inicial es un carácter no emparejado como / o una puntuación de cierre, el delimitador final es el mismo que el delimitador inicial. Por lo tanto, un / termina un qq// construir, mientras que un ] termina ambos qq[] y qq]] constructos.

Al buscar delimitadores de un solo carácter, los delimitadores de escape y \ se omiten. Por ejemplo, mientras busca terminar /, combinaciones de \ y / se omiten. Si los delimitadores están entre corchetes, también se omiten los pares anidados. Por ejemplo, mientras busca un cierre ] emparejado con la apertura [, combinations of \, ], y [ are all skipped, and nested [ and ] también se omiten. Sin embargo, cuando se utilizan barras diagonales inversas como delimitadores (como qq\ y tr\), no se omite nada. Durante la búsqueda del final, las barras invertidas que escapan a los delimitadores u otras barras invertidas se eliminan (hablando exactamente, no se copian en la ubicación segura).

Para construcciones con delimitadores de tres partes (s///, y///, y tr///), la búsqueda se repite una vez más. Si el primer delimitador no es una puntuación de apertura, los tres delimitadores deben ser iguales, como s!!! y tr))), en cuyo caso el segundo delimitador termina la parte izquierda y comienza la parte derecha a la vez. Si la parte izquierda está delimitada por la puntuación entre corchetes (es decir, (), [], {}, o <>), la parte derecha necesita otro par de delimitadores como s(){} y tr[]//. En estos casos, se permiten espacios en blanco y comentarios entre las dos partes, aunque el comentario debe seguir al menos un carácter de espacio en blanco; de lo contrario, un carácter esperado como inicio del comentario puede considerarse como el delimitador inicial de la parte derecha.

Durante esta búsqueda no se presta atención a la semántica del constructo. Por lo tanto:

"$hash{"$foo/$bar"}"

o:

m/
  bar       # NOT a comment, this slash / terminated m//!
 /x

no forme expresiones legales entre comillas. La parte citada termina en la primera " y /, y el resto resulta ser un error de sintaxis. Porque la barra que terminó m// fue seguido por un SPACE, el ejemplo anterior no es m//x, sino más bien m// sin /x modificador. Entonces el incrustado # se interpreta como un literal #.

Además, no se presta atención a c (sintaxis de caracteres de control multichar) durante esta búsqueda. Así, el segundo en qq/c/ se interpreta como parte de /, y lo siguiente / no se reconoce como delimitador. En su lugar, use 34 o x1c al final de los constructos citados.

Interpolación

El siguiente paso es la interpolación en el texto obtenido, que ahora es independiente del delimitador. Hay varios casos.

<<'EOF'

No se realiza ninguna interpolación. Tenga en cuenta que la combinación \ se deja intacto, ya que los delimitadores de escape no están disponibles para here-docs.

m'', el patrón de s'''

En esta etapa no se realiza ninguna interpolación. Cualquier secuencia con barra invertida, incluida \ se tratan en la etapa para “analizar expresiones regulares”.

'', q//, tr''', y''', el reemplazo de s'''

La única interpolación es la eliminación de de pares de \. Por lo tanto "-" en tr''' y y''' se trata literalmente como un guión y no hay ningún rango de caracteres disponible. 1 en el reemplazo de s''' no funciona como $1.

tr///, y///

No se produce interpolación de variables. Combinaciones de modificación de cadenas para mayúsculas y minúsculas, como Q, U, y E no son reconocidos. Las otras secuencias de escape como 200 y t y caracteres con barra invertida como \ y - se convierten en literales apropiados. El personaje "-" es tratado especialmente y por lo tanto - se trata como un literal "-".

"", ``, qq//, qx//, <file*glob>, <<"EOF"

Q, U, u, L, l, F (posiblemente emparejado con E) se convierten en las correspondientes construcciones de Perl. Por lo tanto, "$fooQbaz$bar" se convierte en $foo . (quotemeta("baz" . $bar)) internamente. Las otras secuencias de escape como 200 y t y caracteres con barra invertida como \ y - se reemplazan con expansiones apropiadas.

Que se recalque que lo que sea que se encuentre entre Q y E se interpola de la forma habitual. Algo como "Q\E" no tiene E dentro. En cambio, tiene Q, \, y E, por lo que el resultado es el mismo que para "\\E". Como regla general, las barras invertidas entre Q y E puede conducir a resultados contrarios a la intuición. Entonces, "QtE" se convierte en quotemeta("t"), que es lo mismo que "\t" (dado que TAB no es alfanumérico). Tenga en cuenta también que:

$str = 't';
return "Q$str";

puede estar más cerca de las conjeturas intención del escritor de "QtE".

Los escalares y matrices interpolados se convierten internamente al join y "." operaciones de catenation. Por lo tanto, "$foo XXX '@arr'" se convierte en:

$foo . " XXX '" . (join $", @arr) . "'";

Todas las operaciones anteriores se realizan simultáneamente, de izquierda a derecha.

Porque el resultado de "Q STRING E" tiene todos los metacaracteres citados, no hay forma de insertar un literal $ o @ dentro de una QE par. Si está protegido por , $ se cotizará para convertirse en "\$"; si no, se interpreta como el inicio de un escalar interpolado.

Tenga en cuenta también que el código de interpolación debe tomar una decisión sobre dónde termina el escalar interpolado. Por ejemplo, si "a $x -> {c}" realmente significa:

"a " . $x . " -> {c}";

o:

"a " . $x -> {c};

La mayoría de las veces, el texto más largo posible que no incluye espacios entre componentes y que contiene llaves o corchetes coincidentes. debido a que el resultado puede determinarse votando basándose en estimadores heurísticos, el resultado no es estrictamente predecible. Afortunadamente, suele ser correcto para casos ambiguos.

el reemplazo de s///

Procesamiento de Q, U, u, L, l, F y la interpolación ocurre como con qq// constructos.

Es en este paso que 1 se convierte a regañadientes en $1 en el texto de reemplazo de s///, para corregir el incorregible sed hackers que aún no han aprendido un idioma más sano. Se emite una advertencia si el use warnings pragma o el -w indicador de línea de comandos (es decir, el $^W variable).

RE en m?RE?, /RE/, m/RE/, s/RE/foo/,

Procesamiento de Q, U, u, L, l, F, E, y la interpolación ocurre (casi) como con qq// constructos.

Procesamiento de N{...} también se hace aquí y se compila en una forma intermedia para el compilador de expresiones regulares. (Esto se debe a que, como se menciona a continuación, la compilación de expresiones regulares se puede realizar en el momento de la ejecución, y N{...} es una construcción en tiempo de compilación).

Sin embargo, cualquier otra combinación de seguidos de un carácter no se sustituyen, solo se omiten, para analizarlos como expresiones regulares en el siguiente paso. Como c se omite en este paso, @ de [email protected] en RE posiblemente se trate como un símbolo de matriz (por ejemplo @foo), aunque el mismo texto en qq// da la interpolación de [email protected].

Bloques de código como (?{BLOCK}) se manejan devolviendo temporalmente el control al analizador perl, de manera similar a una expresión de subíndice de matriz interpolada como "foo$array[1+f("[xyz")]bar" sería.

Además, en el interior (?{BLOCK}), (?# comment )y un #-comentar en un /x-expresión regular, no se realiza ningún procesamiento. Este es el primer paso en el que la presencia del /x el modificador es relevante.

La interpolación en patrones tiene varias peculiaridades: $|, $(, $), @+ y @- no se interpolan, y las construcciones $var[SOMETHING] son votados (por varios estimadores diferentes) para ser un elemento de matriz o $var seguido de una alternativa RE. Aquí es donde la notación ${arr[$bar]} viene muy bien: /${arr[0-9]}/ se interpreta como elemento de matriz -9, no como una expresión regular de la variable $arr seguido de un dígito, que sería la interpretación de /$arr[0-9]/. Dado que puede ocurrir una votación entre diferentes estimadores, el resultado no es predecible.

La falta de procesamiento de \ crea restricciones específicas sobre el texto posprocesado. Si el delimitador es /, no se puede obtener la combinación / en el resultado de este paso. / terminará la expresión regular, / será despojado de / en el paso anterior, y \/ se dejará como está. Porque / es equivalente a / dentro de una expresión regular, esto no importa a menos que el delimitador sea un carácter especial para el motor RE, como en s*foo*bar*, m[foo], o m?foo?; o un carácter alfanumérico, como en:

m m ^ a s* b mmx;

En el RE anterior, que se confunde intencionalmente con fines ilustrativos, el delimitador es m, el modificador es mx, y después de la eliminación del delimitador, el RE es el mismo que para m/ ^ a s* b /mx. Hay más de una razón por la que le recomendamos que restrinja sus delimitadores a opciones que no sean alfanuméricas ni espacios en blanco.

Este paso es el último para todas las construcciones excepto las expresiones regulares, que se procesan más.

analizar expresiones regulares

Los pasos anteriores se realizaron durante la compilación del código Perl, pero éste ocurre en tiempo de ejecución, aunque puede optimizarse para ser calculado en tiempo de compilación si es apropiado. Después del preprocesamiento descrito anteriormente, y posiblemente después de la evaluación si están involucradas la concatenación, la unión, la traducción de mayúsculas o las metacitas, el resultado cuerda se pasa al motor RE para su compilación.

Sea lo que sea lo que suceda en el motor RE, podría discutirse mejor en perlre, pero en aras de la continuidad, lo haremos aquí.

Este es otro paso donde la presencia del /x el modificador es relevante. El motor RE escanea la cadena de izquierda a derecha y la convierte en un autómata finito.

Los caracteres con barra invertida se reemplazan con las cadenas literales correspondientes (como con {), o bien generan nodos especiales en el autómata finito (como con b). Caracteres especiales para el motor RE (como |) generan los nodos o grupos de nodos correspondientes. (?#...) los comentarios se ignoran. Todo el resto se convierte en cadenas literales para que coincidan, o bien se ignora (al igual que los espacios en blanco y #-estilo comentarios si /x está presente).

Análisis de la construcción de clase de caracteres entre corchetes, [...], es bastante diferente a la regla utilizada para el resto del patrón. El terminador de esta construcción se encuentra usando las mismas reglas que para encontrar el terminador de un {}-construcción delimitada, la única excepción es que ] siguiendo inmediatamente [ is treated as though preceded by a backslash.

The terminator of runtime (?{...}) is found by temporarily switching control to the perl parser, which should stop at the point where the logically balancing terminating } is found.

It is possible to inspect both the string given to RE engine and the resulting finite automaton. See the arguments debug/debugcolor in the use re pragma, as well as Perl’s -Dr command-line switch documented in “Command Switches” in perlrun.

Optimization of regular expressions

This step is listed for completeness only. Since it does not change semantics, details of this step are not documented and are subject to change without notice. This step is performed over the finite automaton that was generated during the previous pass.

It is at this stage that split() silently optimizes /^/ to mean /^/m.

I/O Operators

There are several I/O operators you should know about.

A string enclosed by backticks (grave accents) first undergoes double-quote interpolation. It is then interpreted as an external command, and the output of that command is the value of the backtick string, like in a shell. In scalar context, a single string consisting of all output is returned. In list context, a list of values is returned, one per line of output. (You can set $/ to use a different line terminator.) The command is executed each time the pseudo-literal is evaluated. The status value of the command is returned in $? (see perlvar for the interpretation of $?). Unlike in csh, no translation is done on the return data–newlines remain newlines. Unlike in any of the shells, single quotes do not hide variable names in the command from interpretation. To pass a literal dollar-sign through to the shell you need to hide it with a backslash. The generalized form of backticks is qx//, or you can call the “readpipe” in perlfunc function. (Because backticks always undergo shell expansion as well, see perlsec for security concerns.)

In scalar context, evaluating a filehandle in angle brackets yields the next line from that file (the newline, if any, included), or undef at end-of-file or on error. When $/ is set to undef (sometimes known as file-slurp mode) and the file is empty, it returns '' the first time, followed by undef subsequently.

Ordinarily you must assign the returned value to a variable, but there is one situation where an automatic assignment happens. If and only if the input symbol is the only thing inside the conditional of a while statement (even if disguised as a for(;;) loop), the value is automatically assigned to the global variable $_, destroying whatever was there previously. (This may seem like an odd thing to you, but you’ll use the construct in almost every Perl script you write.) The $_ variable is not implicitly localized. You’ll have to put a local $_; before the loop if you want that to happen. Furthermore, if the input symbol or an explicit assignment of the input symbol to a scalar is used as a while/for condition, then the condition actually tests for definedness of the expression’s value, not for its regular truth value.

Thus the following lines are equivalent:

while (defined($_ = <STDIN>)) { print; }
while ($_ = <STDIN>) { print; }
while (<STDIN>) { print; }
for (;<STDIN>;) { print; }
print while defined($_ = <STDIN>);
print while ($_ = <STDIN>);
print while <STDIN>;

This also behaves similarly, but assigns to a lexical variable instead of to $_:

while (my $line = <STDIN>) { print $line }

In these loop constructs, the assigned value (whether assignment is automatic or explicit) is then tested to see whether it is defined. The defined test avoids problems where the line has a string value that would be treated as false by Perl; for example a “” or a "0" with no trailing newline. If you really mean for such values to terminate the loop, they should be tested for explicitly:

while (($_ = <STDIN>) ne '0') { ... }
while (<STDIN>) { last unless $_; ... }

In other boolean contexts, <FILEHANDLE> without an explicit defined test or comparison elicits a warning if the use warnings pragma or the -w command-line switch (the $^W variable) is in effect.

The filehandles STDIN, STDOUT, and STDERR are predefined. (The filehandles stdin, stdout, and stderr will also work except in packages, where they would be interpreted as local identifiers rather than global.) Additional filehandles may be created with the open() function, amongst others. See perlopentut and “https://foroayuda.es/perl/open” in perlfunc for details on this.

If a <FILEHANDLE> is used in a context that is looking for a list, a list comprising all input lines is returned, one line per list element. It’s easy to grow to a rather large data space this way, so use with care.

<FILEHANDLE> may also be spelled readline(*FILEHANDLE). See “readline” in perlfunc.

The null filehandle <> is special: it can be used to emulate the behavior of sed and awk, and any other Unix filter program that takes a list of filenames, doing the same to each line of input from all of them. Input from <> comes either from standard input, or from each file listed on the command line. Here’s how it works: the first time <> is evaluated, the @ARGV array is checked, and if it is empty, $ARGV[0] se establece en "-", que cuando se abre le proporciona una entrada estándar. los @ARGV Luego, la matriz se procesa como una lista de nombres de archivo. El lazo

while (<>) {
    ...                     # code for each line
}

es equivalente al siguiente pseudocódigo similar a Perl:

unshift(@ARGV, '-') unless @ARGV;
while ($ARGV = shift) {
    open(ARGV, $ARGV);
    while (<ARGV>) {
        ...         # code for each line
    }
}

excepto que no es tan engorroso decirlo, y realmente funcionará. Realmente cambia el @ARGV matriz y poner el nombre de archivo actual en el $ARGV variable. También usa filehandle ARGV internamente. <> es solo un sinónimo de <ARGV>, que es mágico. (El pseudocódigo anterior no funciona porque trata <ARGV> como no mágico.)

Dado que el identificador de archivo nulo usa la forma de dos argumentos de “https://foroayuda.es/perl/open” en perlfunc, interpreta caracteres especiales, por lo que si tiene un script como este:

while (<>) {
    print;
}

y llámalo con perl dangerous.pl 'rm -rfv *|', en realidad abre una tubería, ejecuta el rm comando y lee rmsalida de esa tubería. Si quieres todos los elementos en @ARGV para ser interpretado como nombres de archivo, puede usar el módulo ARGV::readonly de CPAN, o utilice el corchete doble:

while (<<>>) {
    print;
}

El uso de corchetes angulares dobles dentro de un while hace que el abierto use la forma de tres argumentos (siendo el segundo argumento <), por lo que todos los argumentos en ARGV se tratan como nombres de archivo literales (incluidos "-"). (Tenga en cuenta que, por conveniencia, si utiliza <<>> y si @ARGV está vacío, seguirá leyendo de la entrada estándar).

Puedes modificar @ARGV antes del primero <> siempre que la matriz termine conteniendo la lista de nombres de archivo que realmente desea. Línea de números ($.) continúan como si la entrada fuera un gran archivo feliz. Vea el ejemplo en “eof” en perlfunc para saber cómo restablecer los números de línea en cada archivo.

Si quieres configurar @ARGV a su propia lista de archivos, continúe. Esto establece @ARGV a todos los archivos de texto sin formato si no @ARGV se le dio:

@ARGV = grep { -f && -T } glob('*') unless @ARGV;

Incluso puede configurarlos para canalizar comandos. Por ejemplo, esto filtra automáticamente los argumentos comprimidos a través de gzip:

@ARGV = map { /.(gz|Z)$/ ? "gzip -dc < $_ |" : $_ } @ARGV;

Si desea pasar conmutadores a su secuencia de comandos, puede utilizar uno de los Getopts módulos o poner un bucle en el frente como este:

while ($_ = $ARGV[0], /^-/) {
    shift;
    last if /^--$/;
    if (/^-D(.*)/) { $debug = $1 }
    if (/^-v/)     { $verbose++  }
    # ...           # other switches
}

while (<>) {
    # ...           # code for each line
}

los <> el símbolo volverá undef para el final del archivo solo una vez. Si lo vuelve a llamar después de esto, asumirá que está procesando otra @ARGV lista, y si no ha configurado @ARGV, leerá la entrada de STDIN.

Si lo que contienen los corchetes angulares es una variable escalar simple (por ejemplo, $foo), entonces esa variable contiene el nombre del identificador de archivo desde el que se ingresa, o su typeglob, o una referencia al mismo. Por ejemplo:

$fh = *STDIN;
$line = <$fh>;

Si lo que está dentro de los corchetes angulares no es ni un identificador de archivo ni una variable escalar simple que contenga un nombre de identificador de archivo, typeglob o referencia de typeglob, se interpreta como un patrón de nombre de archivo para ser globled y como una lista de nombres de archivo o el siguiente nombre de archivo en la lista. se devuelve, según el contexto. Esta distinción se determina únicamente sobre bases sintácticas. Eso significa <$x> es siempre un readline() de un mango indirecto, pero <$hash{key}> es siempre un glob(). Eso es porque $x es una variable escalar simple, pero $hash{key} no lo es, es un elemento hash. Incluso <$x > (tenga en cuenta el espacio extra) se trata como glob("$x "), no readline($x).

Primero se realiza un nivel de interpretación de comillas dobles, pero no se puede decir <$foo> porque es un identificador de archivo indirecto como se explica en el párrafo anterior. (En versiones anteriores de Perl, los programadores insertaban llaves para forzar la interpretación como un nombre de archivo glob: <${foo}>. En estos días, se considera más limpio llamar a la función interna directamente como glob($foo), que es probablemente la forma correcta de hacerlo en primer lugar). Por ejemplo:

while (<*.c>) {
    chmod 0644, $_;
}

es aproximadamente equivalente a:

open(FOO, "echo *.c | tr -s ' trf' '\012\012\012\012'|");
while (<FOO>) {
    chomp;
    chmod 0644, $_;
}

excepto que el globbing se realiza internamente utilizando el estándar File::Glob extensión. Por supuesto, la forma más corta de hacer lo anterior es:

chmod 0644, <*.c>;

Un (archivo) glob evalúa su argumento (incrustado) solo cuando está comenzando una nueva lista. Todos los valores deben leerse antes de que comience de nuevo. En el contexto de la lista, esto no es importante porque automáticamente los obtienes todos de todos modos. Sin embargo, en el contexto escalar, el operador devuelve el siguiente valor cada vez que se llama, o undef cuando la lista se haya agotado. Al igual que con las lecturas del identificador de archivos, un defined se genera cuando el glob ocurre en la parte de prueba de un while, porque devuelve glob legal (por ejemplo, un archivo llamado 0) de lo contrario terminaría el ciclo. De nuevo, undef se devuelve solo una vez. Entonces, si espera un valor único de un glob, es mucho mejor decir

($file) = <blurch*>;

que

$file = <blurch*>;

porque este último alternará entre devolver un nombre de archivo y devolver falso.

Si está tratando de hacer una interpolación de variables, definitivamente es mejor usar el glob() función, porque la notación más antigua puede hacer que las personas se confundan con la notación de identificador de archivo indirecto.

@files = glob("$dir/*.[ch]");
@files = glob($files[$i]);

Si se utiliza una expresión globbing basada en corchetes angulares como condición de una while o for bucle, entonces se asignará implícitamente a $_. Si se utiliza una expresión globbing o una asignación explícita de una expresión globbing a un escalar como while/for condición, entonces la condición realmente prueba la definición del valor de la expresión, no su valor de verdad regular.

Plegado constante

Como C, Perl hace una cierta cantidad de evaluación de expresiones en tiempo de compilación siempre que se determine que todos los argumentos de un operador son estáticos y no tienen efectos secundarios. En particular, la concatenación de cadenas ocurre en tiempo de compilación entre literales que no realizan sustitución de variables. La interpolación de barra invertida también ocurre en tiempo de compilación. Puedes decir

  'Now is the time for all'
. "n"
.  'good men to come to.'

y todo esto se reduce a una sola cuerda internamente. Del mismo modo, si dices

foreach $file (@filenames) {
    if (-s $file > 5 + 100 * 2**16) {  }
}

el compilador calcula previamente el número que representa esa expresión para que el intérprete no tenga que hacerlo.

Sin operaciones

Perl no tiene oficialmente un operador sin operación, pero las constantes básicas 0 y 1 tienen una carcasa especial para no producir una advertencia en un contexto nulo, por lo que puede, por ejemplo, hacer

1 while foo();

Operadores de cadena bit a bit

Los operadores bit a bit pueden manipular cadenas de bits de cualquier tamaño (~ | & ^).

Si los operandos de una operación binaria bit a bit son cadenas de diferentes tamaños, | y ^ Las operaciones actúan como si el operando más corto tuviera bits cero adicionales a la derecha, mientras que el Y op actúa como si el operando más largo se truncara a la longitud del más corto. La granularidad de dicha extensión o truncamiento es de uno o más bytes.

# ASCII-based examples
print "j p n" ^ " a h";            # prints "JAPHn"
print "JA" | "  phn";              # prints "japhn"
print "japhnJunk" & '_____';       # prints "JAPHn";
print 'p N$' ^ " E<Hn";            # prints "Perln";

Si tiene la intención de manipular cadenas de bits, asegúrese de proporcionar cadenas de bits: si un operando es un número, eso implicará una numérico operación bit a bit. Puede mostrar explícitamente qué tipo de operación desea realizar utilizando "" o 0+, como en los ejemplos siguientes.

$foo =  150  |  105;        # yields 255  (0x96 | 0x69 is 0xFF)
$foo = '150' |  105;        # yields 255
$foo =  150  | '105';       # yields 255
$foo = '150' | '105';       # yields string '155' (under ASCII)

$baz = 0+$foo & 0+$bar;     # both ops explicitly numeric
$biz = "$foo" ^ "$bar";     # both ops explicitly stringy

Este comportamiento algo impredecible se puede evitar con la función “bit a bit”, nueva en Perl 5.22. Puede habilitarlo a través de use feature 'bitwise' o use v5.28. Antes de Perl 5.28, solía emitir una advertencia en el "experimental::bitwise" categoría. Bajo esta función, los cuatro operadores bit a bit estándar (~ | & ^) son siempre numéricos. Añadiendo un punto después de cada operador (~. |. &. ^.) lo obliga a tratar sus operandos como cadenas:

use feature "bitwise";
$foo =  150  |  105;        # yields 255  (0x96 | 0x69 is 0xFF)
$foo = '150' |  105;        # yields 255
$foo =  150  | '105';       # yields 255
$foo = '150' | '105';       # yields 255
$foo =  150  |. 105;        # yields string '155'
$foo = '150' |. 105;        # yields string '155'
$foo =  150  |.'105';       # yields string '155'
$foo = '150' |.'105';       # yields string '155'

$baz = $foo &  $bar;        # both operands numeric
$biz = $foo ^. $bar;        # both operands stringy

Las variantes de asignación de estos operadores (&= |= ^= &.= |.= ^.=) se comportan de la misma manera bajo la función.

Es un error fatal si un operando contiene un carácter cuyo valor ordinal está por encima de 0xFF y, por lo tanto, no se puede expresar excepto en UTF-8. La operación se realiza en una copia que no es UTF-8 para otros operandos codificados en UTF-8. Consulte “Semántica de bytes y caracteres” en perlunicode.

Consulte “vec” en perlfunc para obtener información sobre cómo manipular bits individuales en un vector de bits.

Aritmética de enteros

Por defecto, Perl asume que debe hacer la mayor parte de su aritmética en coma flotante. Pero al decir

use integer;

puede decirle al compilador que use operaciones con números enteros (vea el número entero para una explicación detallada) desde aquí hasta el final del BLOQUE adjunto. Un BLOQUE interno puede contrarrestar esto diciendo

no integer;

que dura hasta el final de ese BLOQUE. Tenga en cuenta que esto no significa que todo sea un número entero, simplemente que Perl usará operaciones de números enteros para operadores aritméticos, de comparación y bit a bit. Por ejemplo, incluso bajo use integer, si tomas el sqrt(2), todavía obtendrás 1.4142135623731 más o menos.

Usado en números, los operadores bit a bit (& | ^ ~ << >>) siempre producen resultados integrales. (Pero consulte también “Operadores de cadenas de bits”.) Sin embargo, use integer todavía tiene significado para ellos. Por defecto, sus resultados se interpretan como enteros sin signo, pero si use integer está en efecto, sus resultados se interpretan como enteros con signo. Por ejemplo, ~0 generalmente se evalúa como un valor integral grande. Sin embargo, use integer; ~0 es -1 en máquinas en complemento a dos.

Aritmética de coma flotante

Tiempo use integer proporciona aritmética de solo enteros, no existe un mecanismo análogo para proporcionar redondeo o truncamiento automático a un cierto número de lugares decimales. Para redondear a un cierto número de dígitos, sprintf() o printf() suele ser la ruta más fácil. Ver perlfaq4.

Los números de coma flotante son solo aproximaciones a lo que un matemático llamaría números reales. Hay infinitamente más reales que flotadores, por lo que se deben cortar algunas esquinas. Por ejemplo:

printf "%.20gn", 123456789123456789;
#        produces 123456789123456784

Probar la igualdad o desigualdad de punto flotante exacto no es una buena idea. Aquí hay una solución alternativa (relativamente costosa) para comparar si dos números de punto flotante son iguales a un número particular de lugares decimales. Consulte Knuth, volumen II, para un tratamiento más sólido de este tema.

sub fp_equal {
    my ($X, $Y, $POINTS) = @_;
    my ($tX, $tY);
    $tX = sprintf("%.${POINTS}g", $X);
    $tY = sprintf("%.${POINTS}g", $Y);
    return $tX eq $tY;
}

El módulo POSIX (parte de la distribución estándar de Perl) implementa ceil(), floor()y otras funciones matemáticas y trigonométricas. los Math::Complex El módulo (parte de la distribución estándar de Perl) define funciones matemáticas que funcionan tanto en números reales como imaginarios. Math::Complex no es tan eficiente como POSIX, pero POSIX no puede funcionar con números complejos.

El redondeo en aplicaciones financieras puede tener serias implicaciones, y el método de redondeo utilizado debe especificarse con precisión. En estos casos, probablemente valga la pena no confiar en el sistema de redondeo que utilice Perl, sino implementar la función de redondeo que necesita usted mismo.

Números más grandes

El estandar Math::BigInt, Math::BigRat, y Math::BigFloat módulos, junto con los bignum, bigint, y bigrat pragmas, proporcionan aritmética de precisión variable y operadores sobrecargados, aunque actualmente son bastante lentos. A costa de algo de espacio y una velocidad considerable, evitan las trampas normales asociadas con las representaciones de precisión limitada.

    use 5.010;
    use bigint;  # easy interface to Math::BigInt
    $x = 123456789123456789;
    say $x * $x;
+15241578780673678515622620750190521

O con racionales:

use 5.010;
use bigrat;
$x = 3/22;
$y = 4/6;
say "x/y is ", $x/$y;
say "x*y is ", $x*$y;
x/y is 9/44
x*y is 1/11

Varios módulos le permiten calcular con precisión ilimitada o fija (limitada solo por la memoria y el tiempo de la CPU). También hay algunos módulos no estándar que proporcionan implementaciones más rápidas a través de bibliotecas C externas.

Aquí hay un resumen breve, pero incompleto:

Math::String           treat string sequences like numbers
Math::FixedPrecision   calculate with a fixed precision
Math::Currency         for currency calculations
Bit::Vector            manipulate bit vectors fast (uses C)
Math::BigIntFast       Bit::Vector wrapper for big numbers
Math::Pari             provides access to the Pari C library
Math::Cephes           uses the external Cephes C library (no
                       big numbers)
Math::Cephes::Fraction fractions via the Cephes library
Math::GMP              another one using an external C library
Math::GMPz             an alternative interface to libgmp's big ints
Math::GMPq             an interface to libgmp's fraction numbers
Math::GMPf             an interface to libgmp's floating point numbers

Elegir sabiamente.