2012-03-26 5 views
2

Ich möchte Tabs in einem Code verwenden, der sie nicht verwendet. Was ich bisher tat Tabs zu implementieren war ziemlich handcrafty:Ersetzen Sie das Wort mit der Häufigkeit, mit der es gefunden wurde

%s/^ /\t/g 
%s/^\t /\t\t/g 
.. 

Frage: Gibt es eine Möglichkeit zwei Räume () durch Register (\t) die Anzahl der Male zu ersetzen war es am Anfang gefunden eine Linie?

+2

Funktioniert das nicht? ':% s// \ t/g'? –

+2

Sie können auch den Befehl ': retab' verwenden. Sage ': setze ts = 2 noet' und dann': retab! '. Setzen Sie dann den Tabstop auf den Wert zurück, den Sie verwenden möchten, z. ': set ts = 4' – glts

+0

@glgts: Ich würde diesen Kommentar als Antwort eingeben, um rep (weil das ist genau das, was das OP will)! – eckes

Antwort

3

Es gibt (mindestens) drei Substitutionstechniken relevant für diesen Fall.

Die erste nutzt den Vorteil der vorherigen Atom-Matching-Syntax zu natürlich einen Schritt der Einrückung zu definieren. Gemäß der Frageanweisung ist ein Einrückungsschritt ein Paar benachbarter Leerzeichen, denen nichts vorangestellt ist, sondern Leerzeichen vom Anfang der Zeile. Nach dieser Definition kann man das tatsächliche Substitutionsmuster von rechts nach links konstruieren.

:%s/\%(^ *\)\@<= /\t/g 

Tatsächlich bezeichnet das Muster, das ein Auftreten von zwei literal Leerzeichen nach einem Null-Breite \@<= Spiel des vorangehenden Atom, das das Muster ^ * in Klammern Gruppierung gewickelten \%(/\). Diese nicht einfangenden Klammern werden anstelle der üblichen einfangenden Klammern verwendet, \(/\), da dort keine weitere Bezugnahme auf die übereinstimmenden führenden Leerzeichen erforderlich ist. Aufgrund des Flags g läuft der obige Befehl :substitute durch das führende Leerzeichenpaar nach und ersetzt jedes einzelne durch ein einzelnes Tabulatorzeichen.

Die zweite Technik hat einen anderen Ansatz.Anstatt separate Einrückungsebenen zu finden, kann man jede der Zeilen, beginnend mit den Leerzeichen , in zwei Zeilen zerlegen: eine enthält die Einrückungsräume der ursprünglichen Zeile, eine andere, die den Rest enthält. Danach ist es einfach, alle Paare von Leerzeichen in der ersten Zeile zu ersetzen und die Zeilen zusammen miteinander zu verketten.

:g/^ /s/^ \+/&\r/|-s/ /\t/g|j! 

Die dritte Idee ist, die führenden Leerzeichen durch Vim scripting Sprache zu verarbeiten. Ein praktischer Weg, dies zu tun, besteht darin, den Ersatz mit einer Ausdruckseigenschaft des Befehls :substitute zu verwenden (siehe :help sub-replace-\=). Startet die Ersatzzeichenfolge des Befehls mit \=, ermöglicht die Übereinstimmungen eines Musters mit Ergebnissen der Auswertung des Ausdrucks , der nach \= angegeben wird, zu ersetzen.

:%s#^ \+#\=repeat("\t",len(submatch(0))/2) 
+0

Einige Wörter der Erklärung? Vielen Dank! – ezdazuzena

+0

Dachte mehr von was '\%', '\ @<=' und so etwas steht. Ich würde wirklich gerne von Ihrer Antwort lernen, nicht nur kopieren und einfügen. Vielen Dank! – ezdazuzena

+0

Noch ein Kommentar: DANKE! +1 und richtig – ezdazuzena

3

Wenn Sie speziell Leerzeichen in Tabs (oder umgekehrt) am Anfang einer Zeile konvertieren möchten, gibt es den nützlichen Befehl :retab, der dafür sorgt. Zum Beispiel:

  • :retab! 2 werden Räume in Gruppen von zwei wandeln
  • :set expandtab Tabs und dann wird :retab! 2 tabstops wandeln (mit der Breite 2) zurück zu Räumen

Siehe :h :retab (und :h 'ts') für die Details.

Dies ist keine allgemeine Lösung für das ursprüngliche Problem, aber ich denke, es deckt den häufigsten Anwendungsfall ab.

+1

@gits: wie in den Kommentaren zu meiner Frage angegeben: Dies wird alle Registerkarten in Leerzeichen ändern. Das ist nicht das, wonach ich gesucht habe. – ezdazuzena

+0

Sie haben Recht. Ich sehe dein Problem jetzt. Jetzt bin ich auch neugierig auf eine funktionierende Lösung ... – glts

+0

@glgs: Sehen Sie sich den Befehl an, der in meiner [Antwort] (http://stackoverflow.com/a/9885445/254635) aufgeführt ist. –

0

Es gibt keine allgemeine Möglichkeit, dies zu tun mit: s regex's. Sie können den Modifikator /g nicht rückwärts aussehen lassen, sonst wäre er unbrauchbar und Sie können nicht zuverlässig überprüfen, ob Sie am Anfang der Zeile stehen, ohne rückwärts zu schauen.

Der einzige Weg, es in der Regel zu tun, ist eine Schleife, etwa so:

:for i in range(100) 
: %s/^\t*\zs /\t/e 
:endfor 

Welche hässlich, langsam und sehr unrecommended ist. Verwenden Sie :retab

+1

Danke, aber wie schon gesagt, Retab ist keine gute Option, da es alle Registerkarten in der Datei betrifft. – ezdazuzena

+0

Wenn Retab nicht das ist, was Sie wollen, verwenden Sie die For-Schleife, die ich zur Verfügung gestellt habe. Das ist wirklich die einzige Möglichkeit, nur die Zeichen am Anfang der Zeile zu ersetzen, wie ich erklärt habe. –

Verwandte Themen