Ist ein Lookaround im Regex-System von vim möglich?

22

Ich bin in vim auf viele Situationen gestoßen, in denen es nützlich wäre, Lookaround-Anweisungen zu haben. Ich habe versucht , die Standard - Lookarounds Syntax ( (?=), (?!)etc ..) , aber es scheint vim dies nicht unterstützt. Hat vim eine äquivalente Syntax für diese Art von Anweisungen?

Immergrüner Baum
quelle

Antworten:

29

"Zoom" -Anker

Zusätzlich zu der Antwort von @ jecxjo gibt es viele Situationen, in denen Sie die Anker \zsmit \zeder Breite Null und anstelle einer positiven Suche verwenden können. Diese Anker definieren den Beginn ( \zs) und das Ende ( \ze) der Übereinstimmung innerhalb des vollständigen Musters.

Beispiele

  • foo\zsbarwird Match barvorangestellt von foo( foonicht Teil des Matchs)
  • foo\zebarwird passen foogefolgt von bar( barnicht Teil des Spiels)
  • myFunction(\zs.*\ze)stimmen mit den Parametern in einem Funktionsaufruf überein (zu Demonstrationszwecken konzentriere ich mich nicht auf gierige oder nicht gierige Übereinstimmungen)

Putting it to use

Diese werden am nützlichsten, wenn Sie den :substituteBefehl verwenden. Zum Beispiel, sagen , dass ich die Parameter in einem Funktionsaufruf ersetzen wollte myFunction()mit foo:

:%s/myFunction(\zs.*\ze)/foo/

Dies wird verlassen myFunction(und )intakt, und Sie müssen sich keine Sorgen machen über sie in Ihrem erfassen Muster oder sie in Ihrem Wiederholung Ersatz .

Sie könnten dies mit der Lookaround-Funktion von Vims Regex tun, aber es ist ziemlich klobig:

:%s/\(myFunction(\)\@<=.*\()\)\@=/foo/

(Ich finde, dass diese Syntax dazu führt, dass ich vergesse, was ich überhaupt versucht habe.)

Manchmal brauchen Sie noch eine Suche

Es gibt immer noch Situationen, in denen Sie nachsehen müssen. Mit \zsund \zesind ideal für einfache Situationen , in denen Sie etwas vor , gefolgt von Text übereinstimmen , gefolgt nach etwas . Aber wenn es komplexer ist, müssen Sie sich wahrscheinlich an die schwerere Lookaround-Syntax halten.

Lustige Tatsache

Obwohl sie erheblich hässlicher sind, sind Vims Lookarounds mächtiger als die in PCRE! Sie unterstützen ein negatives Aussehen mit variabler Länge, was bedeutet, dass Sie behaupten können, dass ein Muster, dessen Länge nicht vorbestimmt ist, nicht vor Ihrer Übereinstimmung liegt.

PCRE unterstützt dies nicht, da es ziemlich rechenintensiv ist. Dies ist in Vim kein großes Problem, da die häufigsten Anwendungsfälle von Regex in der Regel eine interaktive Suche umfassen, bei der die Rechenzeit für den Benutzer kaum wahrnehmbar ist. Sie würden es wahrscheinlich bemerken, wenn es für die Syntaxhervorhebung verwendet würde.

Relevante Hilfethemen

  • :help \zs
  • :help \ze
  • :help perl-patterns
tommcdo
quelle
Die Zoomanker waren mir nicht bekannt. Vielen Dank für die Erklärung.
EvergreenTree
14

Es sieht so aus, als ob dies möglich ist. Es gibt eine einfache Tabelle, um von Perl nach Vim zu gelangen.:h perl-patterns

9. Compare with Perl patterns               *perl-patterns*

Vim's regexes are most similar to Perl's, in terms of what you can do.  The
difference between them is mostly just notation;  here's a summary of where
they differ:

Capability                  in Vimspeak   in Perlspeak
----------------------------------------------------------------
force case insensitivity    \c            (?i)
force case sensitivity      \C            (?-i)
backref-less grouping       \%(atom\)     (?:atom)
conservative quantifiers    \{-n,m}       *?, +?, ??, {}?
0-width match               atom\@=       (?=atom)
0-width non-match           atom\@!       (?!atom)
0-width preceding match     atom\@<=      (?<=atom)
0-width preceding non-match atom\@<!      (?<!atom)
match without retry         atom\@>       (?>atom)

Wenn Sie zum Beispiel die Zeichenfolge haben one two threeund sie onenur dann <space>twoabgleichen möchten, wenn sie folgt, können Sie sie verwenden

/one\(\stwo\)\@=

Dies ähnelt der Perl-Version

m/one(?=\stwo)/
jecxjo
quelle