regex - probar - expresiones regulares perl online
¿Existe una expresión regular compatible con Perl para recortar el espacio en blanco de ambos lados de una cadena? (12)
¿Hay alguna manera de hacer esto en una línea?
$x =~ s/^/s+//;
$x =~ s//s+$//;
En otras palabras, elimine todos los espacios en blanco iniciales y finales de una cadena.
$ x = ~ s / (^ / s +) | (/ s + $) // g;
Aquí tienes: $x =~ s//A/s*(.*?)/s*/z/$1/;
Discutiendo desde lo herético, ¿por qué hacerlo? Todas las soluciones anteriores son "correctas" en el sentido de que recortan el espacio en blanco de ambos lados de la cadena en una pasada, pero ninguna es terriblemente legible (esperemos que tal vez esta ). A menos que la audiencia de su código esté compuesta por codificadores Perl de nivel experto, cada uno de los candidatos anteriores debe tener un comentario que describa lo que hacen (probablemente una buena idea de todos modos). Por el contrario, estas dos líneas logran lo mismo sin usar lookaheads, comodines, midichlorines o cualquier cosa que no sea inmediatamente obvia para un programador de experiencia moderada:
$string =~ s/^/s+//;
$string =~ s//s+$//;
Existe (posiblemente) un golpe de rendimiento, pero mientras no te preocupen unos pocos microsegundos de ejecución, la legibilidad adicional valdrá la pena. EN MI HUMILDE OPINIÓN.
Es gracioso que debas mencionar esto!
Recientemente leí un artículo que analiza el rendimiento de doce (!) Diferentes implementaciones de recorte .
Aunque el artículo utiliza específicamente la implementación de expresiones regex de JavaScript, usa la sintaxis de Perl, por lo que creo que es pertinente para esta discusión.
Mi primera pregunta es ... ¿por qué? No veo que ninguna de las soluciones regexp únicas sea más legible que la expresión regular con la que comenzó. Y seguro que no están ni cerca tan rápido.
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw(:all);
my $a = ''a'' x 1_000;
my @x = (
" $a ",
"$a ",
$a,
" $a"
);
cmpthese(-5,
{
single => sub {
for my $s (@x)
{
my $x = $s;
$x =~ s/^/s+|/s+$//g;
}
},
double => sub {
for my $s (@x)
{
my $x = $s;
$x =~ s/^/s+//;
$x =~ s//s+$//;
}
},
trick => sub {
for my $s (@x)
{
my $x = $s;
s/^/s+//, s//s+$// for $x;
}
},
capture => sub {
for my $s (@x)
{
my $x = $s;
$x =~ s//A/s*(.*?)/s*/z/$1/
}
},
kramercap => sub {
for my $s (@x)
{
my $x = $s;
($x) = $x =~ /^/s*(.*?)/s*$/
}
},
}
);
da resultados en mi máquina de:
Rate single capture kramercap trick double single 2541/s -- -12% -13% -96% -96% capture 2902/s 14% -- -0% -95% -96% kramercap 2911/s 15% 0% -- -95% -96% trick 60381/s 2276% 1981% 1974% -- -7% double 65162/s 2464% 2145% 2138% 8% --
Editar : runrig es correcto, pero con pocos cambios. Actualicé el código para copiar la cadena antes de la modificación, lo que, por supuesto, ralentiza las cosas. También tomé en cuenta la sugerencia de Brian Foy en otra respuesta para usar una cadena más larga (aunque un millón parecía excesivo). Sin embargo, eso también sugiere que antes de elegir el estilo de truco, descubras cuáles son las longitudes de tus cuerdas: las ventajas del truco se reducen con cadenas más cortas. En todo lo que he probado, sin embargo, el doble gana. Y aún es más fácil para los ojos.
Normalmente lo hago así:
($foo) = $foo =~ /^/s*(.*?)/s*$/;
Todo lo que se encuentra entre los espacios iniciales y los espacios finales se agrupa y se devuelve, por lo que puedo asignarlo a la misma variable anterior.
O esto: s//A/s*|/s*/Z//g
Tanktalus muestra un punto de referencia para cuerdas muy pequeñas, pero los problemas empeoran a medida que las cuerdas se hacen más grandes. En su código, cambié la parte superior:
my $a = ''a'' x 1_000_000;
my @x = (
" $a ",
"$a ",
$a,
" $a"
);
Obtengo estos resultados:
Rate single capture trick double
single 2.09/s -- -12% -98% -98%
capture 2.37/s 13% -- -98% -98%
trick 96.0/s 4491% 3948% -- -0%
double 96.4/s 4512% 3967% 0% --
A medida que la cuerda se hace más grande, usar "truco" y "doble" es casi lo mismo, y la solución común que la mayoría de las personas busca, el "único" (incluyéndome a mí, porque no puedo romper ese hábito aunque sé esto ), realmente comienza a chupar.
Cuando mires un punto de referencia, piensa en lo que te está diciendo. Para ver si lo entiendes, cambia los datos y vuelve a intentarlo. Haga arreglos largos, escalares grandes, etc. Hacer bucles, greps o expresiones regulares para encontrar cosas al principio, en el medio y al final. Vea si los nuevos resultados coinciden con su predicción. Averigua cuál es la tendencia. ¿El rendimiento mejora cada vez más, se acerca a un límite, alcanza un punto máximo y luego comienza a disminuir, o algo más?
$var1 =~ s/(^/s*)(.*?)(/s*$)+/$2/;
$x =~ s/^/s*(.*?)/s*$/$1/;
$x =~ s/^/s+|/s+$//g;
o
s/^/s+//, s//s+$// for $x;
s/^/s*(/S*/S)/s*$/$1/