Eu tenho um arquivo com vários padrões de usuário. Quero alterar parte do texto, mas estou tendo dificuldades para encontrar um substituto e um correspondente. 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 gostaria de substituir # Trackpad: ...
porrunning "Trackpad: ..."
Quebrando o problema, eu vim com 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 perguntas específicas:
- Como evitar a pesquisa de
\n
caracteres e garantir#
que não apareça no final do grupo de pesquisa? - Como posso usar efetivamente grupos de captura?
Existem ótimas respostas abaixo. Difícil escolher entre os três, no entanto, sinto que a resposta escolhida é a mais precisa para minhas especificações originais. Eu recomendo que você tente todas as três respostas com o arquivo real para ver como você se sente sobre elas.
fonte
:%s/\v\n\n#\s+(.*)/^M^Mrunning "\1"/
(adicionou a bandeira "mágica"). É realmente difícil escolher uma resposta correta para minha pergunta original, mas acho que essa resposta é a mais próxima da resposta original esperada. É também o único que funciona em todo o arquivo sem a necessidade de selecionar um intervalo.\r
vez de^M
obter novas linhas?Eu usaria algo como:
^#
para corresponder ao#
caractere ancorado no início da linha (isso responde à pergunta 1)\s\+
para corresponder a qualquer espaço em branco uma ou mais vezes\(
iniciar um grupo (isso responde à pergunta 2).\{-}\
corresponder a qualquer caractere 0 ou mais vezes de maneira não gananciosa ; isso é diferente,.*
na medida em que 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 importa\)
para finalizar o subgrupo.:
corresponde a um literal:
Em seguida, substituímos isso pelo texto que você deseja e usamos
\1
para se referir ao grupo que capturamos.A sintaxe da expressão regular é um pouco parecida com a sintaxe do wiki: existem várias, todas elas são parecidas à primeira vista, nenhuma delas é obviamente melhor do que qualquer outra, mas há muitas diferenças.
Hoje, as chamadas expressões regulares "compatíveis com Perl" são o padrão de fato na maioria dos idiomas, mas as expressões regulares do Vim não são compatíveis com expressões compatíveis com Perl! A sintaxe do vim regexp remonta a pelo menos os anos 70, quando Perl nem estava por perto.
Você pode ver isso nos subgrupos, onde você deve usar
\(
e não(
(isso é compatível com a sintaxe 'básica' do POSIX, mas não com a sintaxe 'estendida' mais comum do POSIX ou a sintaxe Perl). Você pode controlar isso adicionando a\v
bandeira em um padrão (consulte:help /\v
para obter detalhes), isso a tornará "mais compatível", mas não completamente (você ainda precisa usar.{-}
correspondências não gananciosas, por exemplo)Portanto, isso pode explicar por que o uso de "um testador de regex" quase, mas não completamente, funciona.
http://www.vimregex.com/ como uma boa visão geral / cheatsheet de regexps do Vim.
fonte
:
. Consulte o arquivo completo para detalhes github.com/squarefrog/dotfiles/blob/master/osx/...Você pode:
#
::/[^#]$/
#\s(.*)
no início da linha:s/\v^#\s(.*)/running "\1"/
Para usar grupos, você precisa:
\(.*\)
ou\v
:s/\v...
Combinando:
fonte