Ich habe einen häufigen Anwendungsfall, wenn ich einen Python-Ausdruck folgendermaßen transformiere:
value 1
value 2
value 3
in
['value 1', 'value 2', 'value 3']
Der einfachste Weg ist vielleicht, ein Mapping zu verwenden, aber ich wollte eine Ersetzung für diese Aufgabe verwenden.
Bisher habe ich:
s/\(.*\n\)\+/[&]/g
Welches Ergebnis in
[value 1
value 2
value 3
]
Dies wirft eine Frage auf, weil ich in der Lage sein möchte, das \(.*\)
, aber nicht das \n
und das Ergebnis des Abgleichs innerhalb eines zu vergleichen '...'
.
Wissen Sie, wie das geht?
regular-expression
replace
nobe4
quelle
quelle
:'<,'>s/\v(.*)\n/'\1', / | s/\v(.*), /[\1]/
Sie könnten dies in eine visuelle Zuordnung umwandeln:xnoremap ,x :s/\v(.*)\n/'\1', / <Bar> s/\v(.*), /[\1]/<CR>
und möglicherweise in eine normale Zuordnung, wenn die Ausdruck befindet sich in einem Absatz:nnoremap ,x :'{+1,'}-1s/\v(.*)\n/'\1', / <Bar> s/\v(.*), /[\1]/<CR>
Hier wäre die Zuordnung,x
.:%! echo "[$(sed "s/.*/'&',/" % | tr '\n' ' ' | sed 's/, $//')]"
Antworten:
Bearbeiten
Es ist möglich, dies in einem Ausdruck zu tun, wenn wir einen "Sub-Replace-Ausdruck" verwenden. Informationen dazu finden Sie unten.
/Bearbeiten
Das Problem hierbei ist, dass Sie zwei verschiedene Dinge tun möchten.
Bearbeiten Sie das Spiel als Ganzes (dh umgeben Sie es mit
[]
)Betreibe jeden Gegenstand im Match (dh umgib ihn mit
'',
)Sie können ganz einfach eines von beiden tun:
:s/\(.\+\n\)\+/[&]/
:%s/\(.\+\)\n/'\1', /
Aber soweit ich weiß, gibt es keine Möglichkeit, beides in einer einzigen Operation zu tun. Ich habe versucht, die richtige Ausgabe mit so etwas wie:
Aber das Problem dabei ist natürlich, dass die
\2
Übereinstimmungen nur mit der letzten Übereinstimmung aus dem zweiten Satz von Speicherklammern übereinstimmen\(\)
und sich vorher an nichts "erinnern". Sie haben also nur die letzte Zeile.Ich würde empfehlen, eine Vor- / Nachbearbeitung mit einem zusätzlichen
:s///
Befehl durchzuführen, um die Zeilenumbrüche vor / nach der Tat zu entfernen. Folgendes habe ich mir ausgedacht1. Zeile (Zeilenumbrüche entfernen)
.,/\n^$/
Dies ist ein Bereichsmodifikator für das Suchen und Ersetzen. Ohne dies wird der Befehl fortfahren, um Ihre gesamte Datei zu verstümmeln. Derzeit geht es von der aktuellen Zeile.
zur nächsten leeren Zeile\n^$
. Ich bin mir nicht sicher, wie Sie die Dinge aufteilen wollten, aber Sie brauchen eine Möglichkeit, es anzuhalten.s/
Der Beginn eines Such- und Ersetzungsbefehls\(.*\)\n
Passen Sie die gesamte Zeile an, speichern Sie jedoch nur das Teil ohne die neue Zeile.'\1',
Ersetzen Sie die Zeile durch die Übereinstimmung, die von einfachen Anführungszeichen umgeben ist, und fügen Sie ein Komma hinzu.2. Zeile (Surround in Klammern)
\(.*\),
Passen Sie die gesamte Zeile an, aber nicht das letzte Komma und Leerzeichen[\1]
Mit Klammern umgeben und überflüssiges Endkomma und Leerzeichen entfernen.Ich werde mich weiter damit befassen, aber im Moment denke ich nicht, dass es mit einem einzigen Ausdruck möglich ist. :(
BEARBEITEN:
Ich habe einen Weg gefunden, dies mit einem Ausdruck zu tun! Intern ist dies eigentlich zwei Substitutionen, aber es ist technisch ein Ausdruck. Folgendes habe ich mir ausgedacht:
:s///
: Ersetzen Sie\v((.+\n)*.+)\n
: Sammelt im Grunde alle nächsten nicht leeren Zeilen und speichert alles bis auf das Finale\n
\=
Ermöglicht die Verwendung eines Ausdrucks im Ersatz (siehe:h sub-replace-expression
)substitute(submatch(1)...)
: Ersetzt alle gespeicherten\n
mit', '
"['" . ... . "']"
: Vorangestellt['
und angehängt']
Dies beginnt an der Position des Cursors und geht so lange, bis eine leere Zeile (
^\n
) gefunden wird. Es\n
ist wichtig, nicht den letzten zu greifen, da wir ohne dieses Bit ein zusätzliches übrig haben',
, das wir am Ende nicht wollen.Einige mögen dies als komplexer betrachten als die vorherige Antwort mit zwei Ausdrücken. Aber ich dachte, ich würde weitermachen und dies hinzufügen, da es tatsächlich möglich ist, es mit einem Ausdruck zu tun. :) :)
quelle
Optisch hervorheben, dann:
Es umgibt jede Zeile, z. B.
['value 1']
verbindet sie alle, ersetzt dann benachbart]
und[
durch Komma-Leerzeichen.Die Dokumentation für das
*
In*j!
ist:help cpo-star
übrigens bei. Das ist etwas schwierig zu finden.quelle
:'<,'>s/\v(.*)(\_.)/['\1']/
und entfernen.\n
, deshalb habe ich es benutzt:join
. Ich hätte das wahrscheinlich erwähnen sollen. :-)'<,'>s/.*/['&']/ | *s/]\_.\[/, /
dann?*s/]\n\[/, /e
.