Wie kann ich mein Match in vim nicht gierig machen?

479

Ich habe eine große HTML-Datei mit vielen Markups, die so aussehen:

<p class="MsoNormal" style="margin: 0in 0in 0pt;">
  <span style="font-size: small; font-family: Times New Roman;">stuff here</span>
</p>

Ich versuche ein Vim-Suchen und Ersetzen durchzuführen, um alle class=""und loszuwerdenstyle="" aber ich habe Probleme machen das Spiel ungreedy.

Mein erster Versuch war dies

%s/style=".*?"//g

aber Vim scheint das nicht zu mögen ?. Leider entfernen die? macht das das Match zu gierig.

Wie kann ich mein Match ungreedy machen?

Mark Biek
quelle
Ich denke, Pauls Antwort ist gut. Nur um das zu sagen "?" bedeutet nicht optional in vim (wenn dies das ist, was Sie mit "?" erreichen möchten)
LB40
14
@LB, in vielen Sprachen ,. *? bedeutet, mit jedem Charakter übereinzustimmen, aber nicht gierig zu sein. Das versucht er zu erreichen.
Randy Morris
Verwandte: Wie Regex Matcher nicht gierig machen? auf Vim SE.
Big McLargeHuge

Antworten:

734

Anstelle von .*Gebrauch .\{-}.

%s/style=".\{-}"//g

Siehe auch :help non-greedy

Randy Morris
quelle
37
Nicht sehr intuitiv, ist das etwas, was nur vim tut?
Ehtesh Choudhury
94
Alles hat seine eigene Sprache für reguläre Ausdrücke ... das ist eines der größten Probleme bei Regex.
Patrick Farrell
35
Viele dieser Werkzeuge reiften ungefähr zur gleichen Zeit und entwickelten unabhängig voneinander ihren eigenen Dialekt einer Sprache mit regulären Ausdrücken. Viele dieser Tools haben auch versucht, verschiedene Probleme zu lösen, sodass es sinnvoll ist, dass die Syntax in diesen Implementierungen möglicherweise sehr unterschiedlich ist. Wir müssen akzeptieren, dass die reale Welt so funktioniert, obwohl dies manchmal unser Leben als Entwickler erschwert. Glücklicherweise bieten viele Tools heutzutage zumindest eine Perl-kompatible Implementierung von Regex. Leider gehört Vim nicht dazu.
Randy Morris
15
Wenn jemand wie ich die Suche standardmäßig auf \v(sehr magische Flagge) setzt, möchten Sie verwenden .{-}.
Jgillman
48
@Shurane @Ziggy Mnemonic: Steuert die Anzahl der Wiederholungen wie {1,3}bei Klammern. Das Minuszeichen -bedeutet: so wenig wie möglich wiederholen (wenig == Minus);)
Ciro Santilli 法轮功 冠状 病 六四 事件 16
58

Die nicht gierige Suche in vim erfolgt mit dem Operator {-}. So was:

%s/style=".\{-}"//g

Probiere es einfach:

:help non-greedy
Vilhelm Gray
quelle
48

Was ist falsch mit

%s/style="[^"]*"//g
Paul Tomblin
quelle
7
Obwohl ich zu meinem eigenen Vorteil die unhöfliche Sache immer noch besser verstehen möchte.
Mark Biek
17

Wenn Sie mit der PCRE-Regex-Syntax vertraut sind, welche

  1. unterstützt den nicht gierigen Operator?, wie Sie in OP gefragt haben; und
  2. erfordert keine Backwhacking-Gruppierungs- und Kardinalitätsoperatoren (eine absolut kontraintuitive Vim-Syntaxanforderung, da Sie keine Literalzeichen abgleichen, sondern Operatoren angeben); und
  3. Sie haben [g] vim mit Perl-Funktion kompiliert, testen mit

    : Merkmale überprüfen und überprüfen; Wenn + Perl da ist, kannst du gehen.

Versuchen Sie es mit Suchen / Ersetzen mit

:perldo s///

Beispiel. Tauschen Sie die src- und alt-Attribute im img-Tag aus:

<p class="logo"><a href="/"><img src="/caminoglobal_en/includes/themes/camino/images/header_logo.png" alt=""></a></p>

:perldo s/(src=".*?")\s+(alt=".*?")/$2 $1/

<p class="logo"><a href="/"><img alt="" src="/caminoglobal_en/includes/themes/camino/images/header_logo.png"></a></p>
FrDarryl
quelle
1
perldofunktioniert gut, hebt aber leider den ausgewählten Test beim Eingeben des regulären Ausdrucks nicht hervor.
mljrg
12

Ich habe festgestellt, dass eine gute Lösung für diese Art von Frage ist:

:%! sed ...

(oder Perl, wenn Sie es vorziehen). Verwenden Sie ein Tool, das Sie bereits kennen, anstatt die Regex-Besonderheiten von vim zu lernen. Mit Perl würde das? Modifikator arbeiten, um das Match zu entkräften.

William Pursell
quelle
2
Ein guter Punkt, aber es ist auch schön /patternzu überprüfen, ob Sie mit dem Muster übereinstimmen, bevor Sie es anwenden und den cModifikator in Ihrem regulären Vim-Ausdruck verwenden :)
João Portela
das ist richtig. Alle Lösungen hier sind nicht annähernd nicht gierig! Wenn Sie [0-9] \ {7} in einer Zeile mit viel Text und mehreren Vorkommen dieses Musters abgleichen müssen, reicht hier keine Lösung aus. Die Lösungen hier funktionieren nur für einfache Dinge (was, um fair zu sein, gefragt wurde). Aber wenn Sie etwas mehr tun als nur bis zum nächsten Zitat zu suchen, hilft vim nicht weiter.
GCB
4

Mit \v(wie in mehreren Kommentaren vorgeschlagen)

:%s/\v(style|class)\=".{-}"//g
JJoao
quelle
2

Das Plugin eregex.vim verarbeitet nicht gierige Perl-Operatoren *?und+?

bain
quelle
@xsilenT github.com/othree/eregex.vim : "Es wird empfohlen, das Skript mit Vundle oder Pathogen zu installieren."
eXe
Entschuldigung, ich weiß nicht, wie man Vundle oder Krankheitserreger benutzt.
Xsilen T
-4

Tag auch,

Die Regexp-Verarbeitung von Vim ist nicht allzu brillant. Ich habe festgestellt, dass die Regexp-Syntax für sed in etwa den Funktionen von vim entspricht.

Normalerweise setze ich die Suchhervorhebung auf (: setze hlsearch) und spiele dann mit dem regulären Ausdruck, nachdem ich einen Schrägstrich eingegeben habe, um in den Suchmodus zu wechseln.

Bearbeiten: Mark, dieser Trick, um gierige Übereinstimmungen zu minimieren, wird auch in Dale Doughertys ausgezeichnetem Buch "Sed & Awk" ( bereinigter Amazon-Link) behandelt ) behandelt.

Kapitel 3 "Grundlegendes zur Syntax regulärer Ausdrücke" ist eine hervorragende Einführung in die primitiveren Regexp-Funktionen von sed und awk. Nur eine kurze Lektüre und sehr zu empfehlen.

HTH

Prost,

Rob Wells
quelle
7
Die Regex-Verarbeitung von Vim ist eigentlich ganz nett. Es kann Dinge tun, die sed nicht kann, wie z. B. Übereinstimmungen mit Zeilen- / Spaltennummern oder Übereinstimmungen basierend auf der sprachspezifischen Klassifizierung von Zeichen als Schlüsselwörter oder Bezeichner oder Leerzeichen. Es hat auch Zusicherungen mit einer Breite von Null und die Möglichkeit, Ausdrücke auf der rechten Seite eines Ersatzes zu platzieren. Wenn Sie es verwenden \v, hilft es, die Syntax viel zu bereinigen.
Brian Carper
1
@ Brian, Prost. Ich werde einen Hilfe-Regex machen und sehen, was ich vermisst habe.
Rob Wells
@RobWells, Sed & Awk , das imho in der Tat ein sehr gutes Buch ist, gibt keine Worte explizit für gierige / faule Quantifizierer aus. Als Beweis, gibt es absolut kein Auftreten der Worte Gier oder gierig in dem Buch, und es gibt nur einen, aber nicht verwandt, das Auftreten des Wortes faul .
Enrico Maria De Angelis
@EnricoMariaDeAngelis ist es, aber das Beispiel bezieht sich nicht explizit auf den Begriff. Es geht darum, wie Sie Ihren regulären Ausdruck so anpassen können, dass der Operator "nicht" verwendet wird, um nicht gierige Übereinstimmungen zu erzielen. Der Begriff gierig und faul kam mit Perls NFA-Engine auf, als sie Bediener einführten, um das Verhalten von gierigen Übereinstimmungen spezifisch zu ändern.
Rob Wells