Expressions régulières multilignes dans Visual Studio

87

Existe-t-il un moyen pour que Visual Studio effectue un remplacement de regex sur plusieurs lignes (laissez la correspondance traverser les limites de ligne)? Je sais que je peux utiliser de nombreux éditeurs pour cela, mais il semble étrange que cette fonctionnalité ait été laissée en dehors de Visual Studio. Est-ce que je manque quelque chose?

Paul Keister
la source

Réponses:

25

Utilisez la boîte de dialogue Remplacer dans les fichiers Ctrl- Shift- Het l'option de ligne unique (?s):

(?s)start.*end

trouve

start
two
three
end

Singleline signifie: chaque fichier est traité comme une seule ligne, le point .correspond à une nouvelle ligne \n. Inconvénient: vous devez utiliser Rechercher tout et tout remplacer, ou remplacer manuellement. Trouver suivant ne fonctionne pas.

Pour la boîte de dialogue non modale Ctrl- Het recherchez ensuite, utilisez (.*\n)*pour faire correspondre n'importe quel nombre de lignes:

start(.*\n)*.*end

Dans tous les cas, vous pouvez remplacer vos résultats par plusieurs lignes en les insérant \n.

Stéphan Stamm
la source
cela fonctionne mais vous voulez le point d'interrogation supplémentaire (avant end) donc ce n'est pas gourmand. ie:start(.*\n)*.*?end
Bloke CAD
4
La version gourmande correspond à autant de caractères que possible entre startet end. Si vous voulez trouver la toute prochaine, endutilisez la version non gourmande:, (?s)start.*?endou start(.*\n)*?.*?end.
Stephan Stamm
Note aux utilisateurs potentiels: ne fonctionne pas depuis Visual Studio 2013. Voir la réponse de Giles Roberts.
relativement_random
@relativement_random: Avez-vous eu des difficultés à utiliser (?s)?
Stephan Stamm
Oui je l'ai fait. Cela fonctionne-t-il toujours pour vous sur les nouvelles versions de VS?
relativement_random
72

Les expressions régulières ont changé dans Visual Studio 2013 . https://msdn.microsoft.com/en-us/library/2k3te2cs(v=vs.120).aspx

Pour faire correspondre une expression sur deux lignes, le code serait maintenant:

StartOfExpression.*\r?\n.*EndOfExpression

Giles Roberts
la source
Merci, cela fonctionne parfaitement, </label>.*\r?\n.*<divoù se \r?\ntrouve l'évidente chariot_return-new_line et .*pour faire correspondre les tabulations / espaces possibles
Sam
J'obtiens
@ ELI7VH Je ne peux pas reproduire votre erreur. Quelle version de Visual Studio utilisez-vous?
Giles Roberts
25

Cela fonctionne aujourd'hui dans Visual Studio 2012:

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

Voyez comment la (.*\n)+?pièce fait la correspondance sur plusieurs lignes, non gourmande.
fooPatternToStartest un modèle d'expression régulière sur votre ligne de départ, tandis que barPatternToEndvotre modèle est à trouver sur une autre ligne ci-dessous, éventuellement plusieurs lignes ci-dessous ...

Exemple trouvé ici .

Simple et efficace :)

Remarque: avant VS2012, le modèle qui fonctionnait était:fooPatternToStart.(.\n)+@.*barPatternToEnd

woohoo
la source
4
note Visual Studio 2012 utilise le même moteur de regex pour rechercher / remplacer que dans le code, donc ce qui précède devient: fooPatternToStart. * (. * \ n) *?. * barPatternToEnd
Brent
@Brent: d'accord, des versions plus récentes de VSTO ont résolu ce problème.
woohoo
que faire si je veux rechercher un texte spécifiquement entre le début et l'arrêt? comme ça? : Edit: sprintf.*(.*\n)+?.*log.*(.*\n)+?.*__func__fonctionne pour rechercher logentre sprintfet __func__, merci! Tho .. il semble regarder dans l'infini pour cela .. s'il n'y avait qu'un moyen de limiter le nombre de lignes
Gizmo
19

Remarque: cette réponse utilise la syntaxe d'expression régulière utilisée dans Visual Studio jusqu'à VS 2012. Dans VS 2013 et versions ultérieures, la syntaxe d'expression régulière a changé.

Vous pouvez inclure \ndans l'expression. À titre d'exemple, voici une expression régulière que j'utilise pour «nettoyer» les scripts SQL générés automatiquement de tout ce qui n'est pas une procédure stockée (il correspondra aux blocs de texte commençant par une ligne contenant «Object:» suivi de quelque chose qui n'est pas "StoredProcedure", puis faire correspondre les lignes suivantes à une ligne se compose du mot "GO"):

/\*+ Object\::b:b~(StoredProcedure)(.*\n)#GO\n
Fredrik Mörk
la source
Remarque: la terminaison de ligne dépend du format du fichier, n'utilisez donc que \ n pour le texte de style Unix, \ r pour le texte de style Mac ou \ r \ n pour le texte de style Windows.
James Wilkins
2
Note II: assurez-vous de ne pas cocher "Match entier" en même temps, sinon cela ne fonctionne pas!
Ed Graham
1
Pourriez-vous ajouter une note indiquant que cette réponse s'applique uniquement à Visual Studio 2012 et versions antérieures, s'il vous plaît?
Giles Roberts
3

vous devrez peut-être utiliser \ r \ n à la fin de votre expression.

Keng
la source
1

Non-gourmand multi-ligne toute capture de caractères, Visual Studio 2013+:

.*?\r?\n.*?

Version gourmande dans la réponse de Giles Roberts.

Miaou
la source
0

Pour tous ceux qui viennent ici en cherchant VS Code, j'utilise ceci pour faire correspondre n'importe quoi de scriptn'importe où avec 2 nouvelles lignes (nouvelles lignes exclues):

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

remplacer scriptet \n\nfaire correspondre tout entre eux.

Ali Tou
la source