2012-07-03 21 views
5

Me gustaría reemplazar cada dos espacios desde el comienzo de cada línea, con una pestaña. He intentado lo siguiente:perl reemplazar el espacio con la pestaña

s/^(\s{2})+/\t/gm; 

no trabajó.

+1

'unexp y -t 2' –

+0

que se reemplazará en la cadena ENTERA, solo necesito al principio de cada línea. – snoofkin

+0

use '--first-only' (gnu unexpand) –

Respuesta

5

Si está leyendo el archivo línea por línea:

$line =~ s/\G[ ]{2}/\t/g; 

Si 'sorbió todo el archivo:

$file =~ s/(?:\G|^)[ ]{2}/\t/mg; 
+0

+1 para \ G, es bastante útil para tales casos.) – raina77ow

+0

se olvidó de la existencia de \ G, ahora ya no lo olvidaré. Gracias – snoofkin

1

Como una solución alternativa, sin el modificador /m puede usar lookbehind positivo. Tal enfoque puede ser útil para los casos en los que usted necesita para comprobar otra cosa, no sólo a partir de la línea, por lo que cuando \m modificador no ayudaría >>

$_ = " 123\n 456\n 789"; 
s/(?:(?<=^)|(?<=\n))\s{2}/\t/g; 
print $_; 

En el código de ejemplo anterior cada /g doble espacio en blanco que está detrás de \s{2} principio de la cadena (?<=^) o (?: .. | ..) nuevo carácter de línea (?<=\n) se reemplaza por la pestaña \t.

2

¿Qué tal this?

my $test_string = " some test stuff\ndivided to\n provide the challenge"; 
$test_string =~ s/^[ ]{2}/\t/gm; 
print $test_string; 

Explicación: \s no es en realidad un solo alias símbolo, sino una clase de caracteres 'espacio en blanco': Incluye tanto \n\ y \t por ejemplo. Si desea reemplazar solo espacios, use espacios en sus expresiones regulares; el establecimiento de una clase de caracteres (en lugar de sólo /^ {2}/... para mí es más fácil de leer (y no romper con la /xmodifier).

Además, si se desea reemplazar sólo dos símbolos de espacio, no es necesario utilizar + cuantificador

ACTUALIZACIÓN:. Si es necesario sustituir cada dos espacios, supongo que haría uso de este lugar:

$test_string =~ s#^((?:[ ]{2})+)#"\t" x (length($1)/2)#gme; 

... o simplemente \ anclaje G como en la respuesta de la Ikegami .

+0

No funciona en cuatro espacios principales. – ikegami

2

Recuerde que el cuantificador + significa "uno o más de", y se aplica a \s{2} que significa "exactamente dos espacios en blanco". Para un ejemplo simple, considere un programa que cree cadenas de cero a diez espacios e intente relacionarlos con un patrón similar.

#! /usr/bin/env perl 

use strict; 
use warnings; 

for (0 .. 10) { 
    $_ = " " x $_; 
    printf "%-13s %s\n", "[$_]:", /^(\s{2})+$/ ? "match!" : "no match."; 
} 

Salida:

[]:   no match. 
[ ]:   no match. 
[ ]:   match! 
[ ]:  no match. 
[ ]:  match! 
[  ]:  no match. 
[  ]:  match! 
[  ]: no match. 
[  ]: match! 
[   ]: no match. 
[   ]: match!

Como está escrito, su patrón sustituye un único carácter de tabulación para cualquier número positivo, incluso de espacios en blanco en la línea de principio de lógica.

No proporciona el contexto más amplio de su código. Desde el uso de los conmutadores /m y /g, supongo que tiene algunos trozos de texto, tal vez todo el contenido de un archivo, en el que desea operar como un todo. El siguiente programa simula esta situación asumida utilizando un documento aquí y reemplaza los dos primeros espacios solo de cada línea con un TAB.

#! /usr/bin/env perl 

use strict; 
use warnings; 

$_ = <<EOText; 
    Three 
    Two 
    Four 
    Five 
Zero 
One 
EOText 

s/^ /\t/mg; 

# for display purposes only 
s/\t/\\t/g; 

print; 

Salida:

\t Three 
\tTwo 
\t Four 
\t Five 
Zero 
One

Tenga en cuenta que el extra comentó s/// no permanecería en el código. Está ahí para agregar contraste entre el espacio y los caracteres TAB.

Si este es el único propósito de su programa, se convierte en un sencillo delineador. Para crear un nuevo archivo con los contenidos modificados, utilice

$ perl -pe 's/^ /\t/' input-file >output-file

Edición en lugar parece

$ perl -i.bak -pe 's/^ /\t/' input-file
+0

+1 para una explicación extensa.) – raina77ow

Cuestiones relacionadas