2009-04-10 20 views
5

Necesito escribir una secuencia de comandos Perl para leer en un archivo y eliminar cualquier cosa dentro de <>, incluso si están en líneas diferentes. Es decir, si la entrada es:¿Cómo puedo eliminar caracteres entre < and > en Perl?

Hello, world. I <enjoy eating 
bagels. They are quite tasty. 
I prefer when I ate a bagel to 
when I >ate a sandwich. <I also 
like >bananas. 

Quiero que la salida sea:

Hello, world. I ate a sandwich. bananas. 

sé cómo hacer esto si el texto es el 1 de acuerdo con una expresión regular. Pero no sé cómo hacerlo con múltiples líneas. En última instancia, debo poder eliminar partes de una plantilla de manera condicional para poder generar archivos parametrizados para archivos de configuración. Pensé que Perl sería un buen lenguaje, pero todavía estoy aprendiendo el truco.

Editar: También necesita más de 1 instancia de <>

Respuesta

4
local $/; 
my $text = <>; 
s/<.*?>//gs; 
print $text; 
+0

Si su cadena se ve así: ghi>, su expresión regular deja 'ghi>'.Si los paréntesis anidados o escapados y otros casos perversos "nunca suceden", la expresión regular está bien. Para manejar casos perversos, use Text :: Balanced, aunque la interfaz sea extraña. – daotoad

6

Es posible que desee echa un vistazo a un módulo de Perl Text::Balanced, que forma parte del núcleo de la distribución. Creo que será de ayuda para ti. En general, uno quiere evitar las expresiones regulares para hacer ese tipo de cosas. Si el texto del tema es probable que tenga un conjunto interno de delimitadores, puede ser muy complicado.

+0

buen consejo, pero no es necesario en este caso. Sin embargo, definitivamente lo tendré en cuenta. – rlbond

6

En Perl:

#! /usr/bin/perl 
use strict; 

my $text = <>; 
$text =~ s/<[^>]*>//g; 
print $text; 

La expresión regular sustituye cualquier cosa que empiece con un < través de la primera> (ambos inclusive) y lo reemplaza con nada. El g es global (más de una vez).

EDIT: incorpora los comentarios de Hynek y el caos

+0

+1 Buen ejemplo (completo)! –

+0

Es un poco ineficaz. Para dividirlo y unirse de nuevo. perl -0777 -pe 's/<[^>] *> // gm' –

+0

el modificador/m no está ayudando. Significa 'tratar como multilínea', es decir, coincide con^y $ en nuevas líneas, no 'esto es multilínea'./s, tratar como una sola línea, es en realidad más de lo que desearía, pero no lo necesita porque su patrón no está relacionado con el espacio en blanco. – chaos

1

ineficaz forma de una sola línea

perl -0777 -pe 's/<.*?>//gs' 

Igual que el programa

local $/; 
my $text = <>; 
s/<.*?>//gs; 
print $text; 

Depende de cómo texto grande que desea convertir aquí es más eficaz un trazador de líneas consumiendo línea por línea

perl -pe 'if ($a) {(s/.*?>// and do {s/<.*?>//g; $a = s/<.*//s;1}) or $_=q{}} else {s/<.*?>//g; $a = s/<.*//s}' 

Igual que el programa

my $a; 
while (<>) { 
    if ($a) { 
     if (s/.*?>//) { 
      s/<.*?>//g; 
      $a = s/<.*//s; 
     } 
     else { $_ = q{} } 
    } 
    else { 
     s/<.*?>//g; 
     $a = s/<.*//s; 
    } 
    print; 
} 
+0

Como se indicó en la respuesta de CoverosGene,/m no es necesario ni útil. – chaos

+0

Sí, tienes razón. –

Cuestiones relacionadas