2012-07-03 11 views
5

Vorrei sostituire ogni due spazi dall'inizio di ogni riga, con una scheda. Ho provato quanto segue:perl sostituire lo spazio con la scheda

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

non ha funzionato.

+1

'unexp e -t 2' –

+0

che sostituirà nella stringa WHOLE, ho bisogno solo all'inizio di ogni riga. – snoofkin

+0

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

risposta

5

Se stai leggendo il file riga per riga:

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

Se ho inghiottito l'intero file:

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

+1 per \ G, è abbastanza utile in questi casi.) – raina77ow

+0

dimenticato l'esistenza di \ G, ora non lo dimenticherò più. Grazie – snoofkin

1

Come soluzione alternativa, senza il modificatore /m è possibile utilizzare il lookbehind positivo. Tale approccio può essere utile per i casi in cui è necessario controllare qualcos'altro, non solo all'inizio della riga, in modo che quando \m modificatore non aiuterebbe >>

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

Nel codice di esempio sopra ogni /g doppia spaziatura \s{2} che sta dietro inizio della stringa (?<=^) o (?: .. | ..) il carattere della nuova riga (?<=\n) viene sostituito dalla scheda \t.

2

Che ne dici di this?

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

Spiegazione: \s non è in realtà un unico alias simbolo, ma un carattere 'spazio bianco' classe: include sia \n\ e \t per esempio. Se vuoi sostituire solo gli spazi, usa gli spazi nelle tue espressioni regolari; impostazione di una classe di caratteri (anziché solo /^ {2}/... per me è più leggibile (e non rompere con la /xmodifier).

Inoltre, se si desidera sostituire solo due simboli spazio, non è necessario per utilizzare + quantificatore

UPDATE:. se è necessario sostituire ogni due spazi, credo che userei questo, invece:

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

... o semplicemente \ anchor G come nella risposta del Ikegami .

+0

Non funziona per quattro spazi iniziali. – ikegami

2

Ricordate che il quantificatore + significa “uno o più”, ed è applicata a \s{2} che significa “esattamente due caratteri di spazio bianco.” Per un semplice esempio, si consideri un programma che crea le stringhe da zero a dieci spazi e tentativi di abbinarli a un modello simile.

#! /usr/bin/env perl 

use strict; 
use warnings; 

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

uscita:

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

Come scritto, il vostro modello sostituisce un singolo carattere TAB per qualsiasi positivo anche il numero di caratteri di spaziatura alla linea inizio-di-logica.

Non si fornisce il contesto più ampio del proprio codice. Dall'uso degli switch /m e, presumo che tu abbia qualche pezzo di testo, forse l'intero contenuto di un file, su cui vuoi operare nel suo insieme. Il programma seguente simula questa situazione ipotizzata usando un documento qui e sostituisce i primi due spazi di ogni riga 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; 

uscita:

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

Si noti che l'extra commentato s/// non rimarrebbe nel codice. È lì per aggiungere contrasto tra spazio e caratteri TAB.

Se questo è l'unico scopo del programma, diventa un semplice supporto. Per creare un nuovo file con i contenuti modificati, utilizzare

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

Modifica in posto sembra

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

+1 per ampia spiegazione.) – raina77ow

Problemi correlati