Mehrzeilige reguläre Ausdrücke in Visual Studio

87

Gibt es eine Möglichkeit, Visual Studio dazu zu bringen, eine Regex-Ersetzung über mehrere Zeilen hinweg durchzuführen (lassen Sie die Übereinstimmung die Zeilengrenzen überschreiten)? Ich weiß, dass ich dafür viele Editoren verwenden kann, aber es scheint seltsam, dass diese Funktion in Visual Studio nicht berücksichtigt wurde. Vermisse ich etwas

Paul Keister
quelle

Antworten:

25

Verwenden Sie das Dialogfeld "In Dateien ersetzen" Ctrl- Shift- Hund die Option "Einzeilig" (?s):

(?s)start.*end

findet

start
two
three
end

Singleline bedeutet: Jede Datei wird als einzelne Zeile behandelt, Punkt .entspricht Newline \n. Nachteil: Sie müssen Find All verwenden und All ersetzen oder von Hand ersetzen. Als nächstes suchen funktioniert nicht.

Verwenden Sie für den nicht modalen Dialog Ctrl- Hund suchen Sie als Nächstes, um (.*\n)*eine beliebige Anzahl von Zeilen abzugleichen:

start(.*\n)*.*end

In beiden Fällen können Sie Ihre Ergebnisse durch Einfügen durch mehrere Zeilen ersetzen \n.

Stephan Stamm
quelle
Dies funktioniert, aber Sie möchten das zusätzliche Fragezeichen (vorher end), damit es nicht gierig ist. dh:start(.*\n)*.*?end
CAD-Typ
3
Die gierige Version entspricht so vielen Zeichen wie möglich zwischen startund end. Wenn Sie den nächsten finden möchten, endverwenden Sie die nicht gierige Version : (?s)start.*?end, oder start(.*\n)*?.*?end.
Stephan Stamm
Hinweis für potenzielle Benutzer: Funktioniert seit Visual Studio 2013 nicht mehr. Siehe die Antwort von Giles Roberts.
relativ
@relativ_random: Hattest du Probleme mit der Verwendung (?s)?
Stephan Stamm
Ja, habe ich. Funktioniert es bei neueren VS-Versionen immer noch für Sie?
relativ
72

Reguläre Ausdrücke haben sich in Visual Studio 2013 geändert . https://msdn.microsoft.com/en-us/library/2k3te2cs(v=vs.120).aspx

Um einen Ausdruck über zwei Zeilen abzugleichen, lautet der Code jetzt:

StartOfExpression.*\r?\n.*EndOfExpression

Giles Roberts
quelle
Vielen Dank, dies funktioniert perfekt, </label>.*\r?\n.*<divwo \r?\nist die offensichtliche carriage_return-new_line und .*für die Übereinstimmung der möglichen Tabulatoren / Leerzeichen
Sam
Ich erhalte die Fehlermeldung "Literal '\ n' wird derzeit nicht unterstützt"
ELI7VH
@ ELI7VH Ich kann Ihren Fehler nicht replizieren. Welche Version von Visual Studio verwenden Sie?
Giles Roberts
25

Dies funktioniert heute in Visual Studio 2012:

fooPatternToStart.*(.*\n)+?.*barPatternToEnd

Sehen Sie, wie der (.*\n)+?Teil die Übereinstimmung über mehrere Zeilen hinweg macht, ohne gierig zu sein.
fooPatternToStartbefindet sich ein Regex-Muster in Ihrer Startzeile, während barPatternToEndsich Ihr Muster in einer anderen Zeile darunter befindet, möglicherweise in vielen Zeilen darunter ...

Beispiel hier gefunden .

Einfach und effektiv :)

Hinweis: Vor VS2012 funktionierte das folgende Muster:fooPatternToStart.(.\n)+@.*barPatternToEnd

woohoo
quelle
4
note Visual Studio 2012 verwendet dieselbe Regex-Engine zum Suchen / Ersetzen wie im Code, daher lautet das oben Gesagte: fooPatternToStart. * (. * \ n) * ?. * barPatternToEnd
Brent
@Brent: Zugegeben, neuere Versionen von VSTO haben dieses Problem behoben.
woohoo
Was ist, wenn ich zwischen Start und Stopp nach einem Text suchen möchte? so was? : Edit: sprintf.*(.*\n)+?.*log.*(.*\n)+?.*__func__arbeitet um logzwischen sprintfund zu suchen __func__, danke! Tho .. es scheint in die Unendlichkeit dafür zu schauen .. wenn es nur eine Möglichkeit gäbe, die Anzahl der Zeilen zu begrenzen
Gizmo
19

Hinweis: In dieser Antwort wird die in Visual Studio bis einschließlich VS 2012 verwendete Regex-Syntax verwendet. In VS 2013 und höher wurde die Regex-Syntax geändert.

Sie können \nin den Ausdruck aufnehmen. Als Beispiel ist hier ein regulärer Ausdruck, den ich verwende, um automatisch generierte SQL-Skripte von allem zu "bereinigen", was keine gespeicherte Prozedur ist (er stimmt mit Textblöcken überein, die mit einer Zeile beginnen, die "Object:" enthält, gefolgt von etwas, das nicht ist "StoredProcedure", das dann die folgenden Zeilen mit einer Zeile verknüpft, besteht aus dem Wort "GO"):

/\*+ Object\::b:b~(StoredProcedure)(.*\n)#GO\n
Fredrik Mörk
quelle
Hinweis: Der Zeilenabschluss hängt vom Format der Datei ab. Verwenden Sie daher nur \ n für Text im Unix-Stil, \ r für Text im Mac-Stil oder \ r \ n für Text im Windows-Stil.
James Wilkins
2
Hinweis II: Stellen Sie sicher, dass Sie nicht gleichzeitig "Ganzes Wort abgleichen" aktiviert haben, da dies sonst nicht funktioniert!
Ed Graham
1
Könnten Sie bitte einen Hinweis hinzufügen, dass diese Antwort nur für Visual Studio 2012 und älter gilt?
Giles Roberts
3

Möglicherweise müssen Sie am Ende Ihres Ausdrucks \ r \ n verwenden.

Keng
quelle
1

Nicht gierige mehrzeilige Zeichenerfassung, Visual Studio 2013+:

.*?\r?\n.*?

Gierige Version in Giles Roberts 'Antwort.

Miau
quelle
0

Für alle, die hierher kommen, während sie nach VS-Code suchen, verwende ich dies, um alles von scriptüberall mit 2 Zeilenumbrüchen abzugleichen (Zeilenumbrüche ausgeschlossen):

script(.|\n)+?(?=\n\n)

ersetzen scriptund \n\nalles zwischen ihnen zusammenbringen.

Ali Tou
quelle