Es sieht so aus, als ob dein böser Regex nicht böse genug war ... :-)
Suchbereich
Die Suche müsste folgendermaßen geändert werden:
^Hide\(\(\(Show\|Hide\)\@!\_.\)*\)SetFontSize 28
Dies beinhaltet einige ungewöhnliche Dinge und so viele Klammern ... Mal sehen, was wir da drin haben:
Das Caret ( ^
)
Mit dem Caret wird der Zeilenanfang bezeichnet. Ich denke, wir sind mit diesem bereits vertraut.
Ein wichtiger Punkt, der ^
funktioniert nur als erstes Zeichen in Ihrem Muster. Nach dem wird es wörtlich genommen. Um einen Zeilenanfang in Ihren Ausdruck aufzunehmen, müssen Sie ihn verwenden \_^
. In unserer Situation brauchten wir das jedoch nicht.
(Es gibt ein ähnliches Phänomen mit $
und \_$
)
Die erste und letzte Klammer ( \( ... \)
)
Die erste und die letzte Klammer werden alleine verwendet, was bedeutet, dass alles, was darin erscheint, erfasst und in den Parameter gesetzt wird \1
. Sie haben das bereits in Ihrem eigenen regulären Ausdruck verwendet, daher gehe ich davon aus, dass Sie auch mit diesem vertraut sind.
Der zweite Satz in Klammern
Wie Sie vielleicht bemerken, gibt es einen zweiten Satz Klammern, gefolgt von einem Sternchen \( ... \)*
. Das heißt, wir suchen nach dem, was beliebig oft passt. Dies ist die übliche Art, das Sternchen zu verwenden, daher sollten Sie damit vertraut sein.
Der dritte Satz von Klammern, OR und \_.
Ja, es gibt tatsächlich drei Klammern vor dem Wort Show
. Dieser letzte Satz ist aus zwei Gründen erforderlich: \|
dem folgenden und dem folgenden @!
.
In Bezug auf die OP-Operation sollten Sie bereits damit vertraut sein.
Show\|Hide or Hide\|Show
Die Reihenfolge spielt hier keine Rolle. Das \
ist vor dem notwendig |
, um in vim zu arbeiten.
Die Klammer um diesen Ausdruck ermöglicht es uns, dem Ausdruck durch etwas zu folgen . Hier die @!
.
\(Show\|Hide\)@!
Dieser ist viel weniger vertraut. Es bedeutet, wenn nicht übereinstimmend . Die Verwendung ist zwar nicht sehr einfach, aber Sie müssen diesem Ausdruck das folgen, was Sie extrahieren möchten, das nicht mit dem Ausdruck übereinstimmen sollte. Deshalb haben wir \_.
hinter diesem Muster.
Die \_.
Mittel passen zu allem. Im Gegensatz zu der .
für sich, die nicht zum \n
Charakter passt . Mit anderen Worten, wir stimmen mit jedem Zeichen in einer beliebigen Anzahl von Zeilen überein, es sei denn, es stimmt mit Show
oder überein Hide
.
Beachten Sie, dass die Klammern um diesen Ausdruck ebenso wichtig sind wie das Sternchen. Das Ganze macht es also wirklich möglich:
\(\(Show\|Hide\)@!\_.\)*
was bis zum nächsten aka übereinstimmen Show
oder Hide
Zeichen (beachten Sie, dass es würde auch passen Showing
, Shower
, HideMe
etc. sollten Sie verwenden können, \<
und \>
wenn es notwendig ist , das Wort genau übereinstimmen.)
Randnotiz: Um in mehreren Zeilen zu suchen, können Sie auch das \n
Zeichen im Muster verwenden. Es ist jedoch nicht so vielseitig als das \_.
Muster.
SetFontSize 28
Jetzt muss der Abschnitt SetFontSize 28
auch enthalten. Genau wie du es in deiner Regex getan hast. Wenn SetFontSize 28
in diesem Abschnitt kein angezeigt wird, wiederholen Sie die Suche im nächsten Abschnitt.
Aufgrund der obigen Negation (die Übereinstimmung außer Show
oder Hide
) geht die Suche nicht zum nächsten Abschnitt über, wodurch das Risiko besteht, dass sie durcheinander gebracht wird.
Ersatzteil
Der Ersatz ist genauso wie Sie ihn hatten:
.../Hide\1SetFontSize 18/
Wir verwenden die Klammern in der Suche, damit das \1
wie erwartet funktioniert.
Vollständige Suche und Ersetzung
Die resultierenden Muster sehen folgendermaßen aus:
:%s/^Hide\(\(\(Show\|Hide\)@!\_.\)*\)SetFontSize 28/Hide\1SetFontSize 18/
Das \(Show\|Hide\)
sollte alle möglichen Header enthalten .
Quellen
Regex für jedes Zeichen, einschließlich Zeilenumbruch ( \_.\{-}
)
Suche nach Zeilen ohne Muster und andere hilfreiche Suchanfragen ( @!
)
Vim-Dokumentation: pattern ( \_^
)
Hide
Block eineSetFontSize
Zeile (was auch immer der Wert sein mag)? Wenn ja, könnten Sie verwenden:%s/Hide\_.\{-\}SetFontSize \zs28/18/