Tenho um arquivo com vários padrões do usuário. Quero alterar parte do texto, mas estou tendo dificuldades chegando com um matcher e substituto. Usando o seguinte exemplo:
############################################################################### # Trackpad, mouse, keyboard, Bluetooth accessories, and input # ############################################################################### # Trackpad: enable tap to click for this user and for the login screen defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true 
 Eu “d gostaria de substituir # Trackpad: ... com running "Trackpad: ..." 
Resolvendo o problema, descobri algo usando um testador de regex:
/\n\n#\s(.*)/g 
Se eu tentar usar isso no Vim, não funcionará para mim:
:/\n\n#\s(.*)/running "\1"/g 
Acho que meu problema se resume a duas questões específicas:
-  Como posso evitar a pesquisa de 
\ncaracteres e, em vez disso, certifique-se de que#não apareça no final do grupo de pesquisa? - Como posso usar grupos de captura de maneira eficaz?
 
Existem algumas respostas excelentes abaixo. É difícil escolher entre as três, no entanto, sinto que a resposta escolhida é a mais precisa para minha especificação original. Recomendo que você tente todas as três respostas com o arquivo real para ver como você se sente a respeito delas.
Resposta
Só para deixar claro… acredito que você pediu que isso fosse o resultado da substituição?
############################################################################### # Trackpad, mouse, keyboard, Bluetooth accessories, and input # ############################################################################### running "Trackpad: enable tap to click for this user and for the login screen" defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true 
Nesse caso, recomendo o seguinte comando:
 :%s/\n\n#\s\+\(.*\)/^M^Mrunning "\1"/ 
Explicação do padrão
 :s/PATTERN/REPLACEMENT/ é o comando  substitute . O sinal de porcentagem em :%s faz com que funcione em todo o arquivo, e não apenas na linha atual. 
 O \n\n diz que a linha de interesse deve ocorrer após uma linha em branco. Se você não se importasse com a linha em branco anterior, ^ seria o suficiente. 
 #\s\+ corresponde a um hash caractere seguido por um ou mais caracteres de espaço em branco. \(.*\) captura todo o texto subsequente na linha. 
Explicação do texto de substituição
 ^M^M insere duas extremidades de linhas para substituir os \n\n que estavam presentes no padrão. Caso contrário, o texto seria movido para o final da linha precedendo a linha em branco. Para digitar cada ^M, pressione  Ctrl-V   Ctrl-M . 
 Em seguida, insira a string running, seguida por tudo o que foi capturado entre parênteses entre aspas duplas. 
Comentários
Resposta
Eu usaria algo como:
:s/^#\s\+\(.\{-}\):/running "\1":/ 
-  
^#para corresponder ao#caractere ancorado no início da linha (responde à pergunta 1) -  
\s\+para corresponder a qualquer espaço em branco uma ou mais vezes -  
\(para iniciar um grupo (responde a pergunta 2) -  
.\{-}\para corresponder a qualquer caractere 0 ou mais vezes em um maneira não gananciosa ; isso é diferente de.*porque tenta corresponder o mínimo possível, e não tanto quanto possível. Tente adicionar um:caractere no comentário para ver por que isso é importante -  
\)para encerrar o subgrupo. -  
:corresponde a um literal: 
 Em seguida, substituímos isso pelo texto que você deseja e use \1 para se referir ao grupo que capturamos. 
Eu descobri algo usando um testador de regex
A sintaxe da expressão regular é um pouco como a sintaxe do wiki: há vários deles, todos parecem iguais à primeira vista, nenhum deles é obviamente melhor do que qualquer outro, mas há muitas diferenças.
Hoje, as chamadas expressões regulares “compatíveis com Perl” são o padrão de fato na maioria das linguagens, mas as expressões regulares do Vim não compatível com expressões compatíveis com Perl! A sintaxe regexp do Vim remonta a pelo menos “70” s, quando Perl não existia.
 Você pode ver isso com os subgrupos, onde você deve usar \( e não ( (isso é compatível com a sintaxe POSIX “básica”, mas não com a sintaxe POSIX “estendida” mais comum ou sintaxe Perl).Você pode controlar isso adicionando o sinalizador \v em um padrão (consulte  :help /\v  para obter detalhes), isso o tornará “mais compatível”, mas não completamente (você ainda precisa usar .{-} para correspondências não gananciosas, por exemplo) 
Portanto, isso pode explicar por que usar “um testador de regex” quase funciona, mas não exatamente.
http://www.vimregex.com/ como uma boa visão geral / cheatsheet de regexps do Vim.
Comentários
-  Ótima resposta, especialmente com why regex! = regex. Quanto à sua pesquisa e substituição, ‘ é um pouco complicado, pois o comentário pode ou não ter um 
:. Veja o arquivo completo para obter detalhes github.com/squarefrog/dotfiles/blob/master/osx/… 
Resposta
Você pode:
-  pesquisar linhas que não terminam em 
#::/[^#]$/ -  substitua 
#\s(.*)no início de a linha:s/\v^#\s(.*)/running "\1"/ 
Para usar grupos, você precisa:
-  escapar os colchetes para que eles se tornam parte da sintaxe regex: 
\(.*\)ou -  use  “magic”  por começando a expressão com 
\v:s/\v... 
Combinando:
:/[^#]$/s/\v^#\s(.*)/running "\1"/ 
Comentários
- Funciona de maneira brilhante, obrigado por incluir uma explicação do significado das tags em vez de apenas o texto que eu precisava escrever.
 - Obrigado por deixar claro que os colchetes têm t o ser escapado para se tornar parte da sintaxe regex. Sempre tive problemas com grupos regex para fazê-los funcionar.
 
:%s/\v\n\n#\s+(.*)/^M^Mrunning "\1"/(adicionou a ” mágica ” sinalizador). É realmente difícil escolher uma resposta correta para minha pergunta original, mas sinto que essa resposta é a mais próxima da minha resposta original esperada. É também o único que funciona em todo o arquivo sem a necessidade de selecionar um intervalo.\rem vez de^Mpara obter novas linhas?