Expressões regulares multilinhas no Visual Studio

87

Existe alguma maneira de fazer com que o Visual Studio execute uma substituição regex em várias linhas (deixe que os limites das linhas cruzadas correspondam)? Sei que há muitos editores que posso usar para isso, mas parece estranho que esse recurso tenha sido deixado de fora do Visual Studio. Estou esquecendo de algo?

Paul Keister
fonte

Respostas:

25

Use a caixa de diálogo substituir em arquivos Ctrl- Shift- He a opção de linha única (?s):

(?s)start.*end

encontra

start
two
three
end

Singleline significa: cada arquivo é tratado como uma única linha, o ponto .corresponde à nova linha \n. Desvantagem: você deve usar Localizar tudo e substituir tudo ou substituir manualmente. Encontrar próximo não funciona.

Para a caixa de diálogo não modal Ctrl- He encontre a seguir, use (.*\n)*para corresponder a qualquer número de linhas:

start(.*\n)*.*end

De qualquer maneira, você pode substituir suas descobertas por várias linhas inserindo \n.

Stephan Stamm
fonte
isso funciona, mas você quer o ponto de interrogação extra (antes end) para que não seja ganancioso. ou seja:start(.*\n)*.*?end
CAD cara de
4
A versão gananciosa corresponde ao máximo de caracteres possível entre starte end. Se você quiser encontrar o próximo, enduse a versão não gananciosa:, (?s)start.*?endou start(.*\n)*?.*?end.
Stephan Stamm
Observação para usuários em potencial: não funciona desde o Visual Studio 2013. Consulte a resposta de Giles Roberts.
relativamente_random
@relativamente_random: Você teve problemas para usar (?s)?
Stephan Stamm
Sim eu fiz. Ainda funciona para você nas versões mais recentes do VS?
relativamente_random
72

As expressões regulares mudaram no Visual Studio 2013 . https://msdn.microsoft.com/en-us/library/2k3te2cs(v=vs.120).aspx

Para corresponder a uma expressão em duas linhas, o código agora seria:

StartOfExpression.*\r?\n.*EndOfExpression

Giles Roberts
fonte
Obrigado, isso funciona perfeitamente, </label>.*\r?\n.*<divonde \r?\nestá a óbvia charge_return-new_line e .*por combinar as tabs / espaços possíveis
Sam
Recebo o erro "Literal '\ n' atualmente não é compatível"
ELI7VH
@ ELI7VH Não consigo replicar seu erro. Qual versão do Visual Studio você está usando?
Giles Roberts
25

Isso funciona hoje no Visual Studio 2012:

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

Veja como a (.*\n)+?peça faz a correspondência em várias linhas, não gananciosa.
fooPatternToStarté algum padrão regex em sua linha de partida, enquanto barPatternToEndé seu padrão para encontrar em outra linha abaixo, possivelmente muitas linhas abaixo ...

Exemplo encontrado aqui .

Simples e eficaz :)

Nota: antes do VS2012, o padrão que funcionava era:fooPatternToStart.(.\n)+@.*barPatternToEnd

woohoo
fonte
4
observe que o visual studio 2012 usa o mesmo mecanismo de regex para localizar / substituir como no código, então o acima se torna: fooPatternToStart. * (. * \ n) *?. * barPatternToEnd
Brent
@Brent: concedido, versões mais recentes do VSTO corrigiram esse problema.
woohoo
e se eu quiser pesquisar um texto especificamente entre o início e o fim? como isso? : Editar: sprintf.*(.*\n)+?.*log.*(.*\n)+?.*__func__funciona para pesquisar logentre sprintfe __func__, obrigado! Tho .. parece olhar para o infinito para isso .. se ao menos houvesse uma maneira de limitar a quantidade de linhas
Gizmo
19

Observação: esta resposta está usando a sintaxe regex usada no Visual Studio até e incluindo o VS 2012. No VS 2013 e posterior, a sintaxe regex foi alterada.

Você pode incluir \nna expressão. Como exemplo, aqui está um regex que eu uso para "limpar" scripts SQL gerados automaticamente de qualquer coisa que não seja um procedimento armazenado (ele corresponderá a blocos de texto que começam com uma linha contendo "Objeto:" seguido por algo que não é "StoredProcedure", em seguida, combinar as seguintes linhas até uma linha consiste na palavra "GO"):

/\*+ Object\::b:b~(StoredProcedure)(.*\n)#GO\n
Fredrik Mörk
fonte
Nota: O terminador de linha depende do formato do arquivo, portanto, use apenas \ n para texto de estilo Unix, \ r para texto de estilo Mac ou \ r \ n para texto de estilo Windows.
James Wilkins de
2
Nota II: certifique-se de que a opção "Corresponder palavra inteira" não esteja marcada ao mesmo tempo, caso contrário, isso não funciona!
Ed Graham
1
Você poderia adicionar uma observação dizendo que esta resposta se aplica apenas ao Visual Studio 2012 e anteriores, por favor?
Giles Roberts
3

você pode precisar usar \ r \ n no final de sua expressão.

Keng
fonte
1

Qualquer captura de caractere multilinha não gananciosa, Visual Studio 2013+:

.*?\r?\n.*?

Versão gananciosa na resposta de Giles Roberts.

Miau
fonte
0

Para todos que vêm aqui enquanto procuram pelo Código VS, eu uso isso para fazer a correspondência de qualquer coisa de scriptqualquer lugar com 2 novas linhas (excluídas as novas linhas):

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

substituir scripte \n\ncombinar tudo entre eles.

Ali Tou
fonte