Respostas:
Você está procurando uma correspondência não gananciosa (ou preguiçosa). Para obter uma correspondência não gananciosa em expressões regulares, você precisa usar o modificador ?
após o quantificador. Por exemplo, você pode mudar .*
para .*?
.
Por padrão grep
, não suporta modificadores não gananciosos, mas você pode usar grep -P
para usar a sintaxe Perl.
.
corresponder às novas linhas é chamado DOTALL ou modo de linha única ; Ruby é o único que chama de multilinha . Nos outros tipos, multilinha é o modo que permite que as âncoras ( ^
e $
) correspondam aos limites da linha. O Ruby não tem um modo equivalente, porque no Ruby eles sempre funcionam dessa maneira.
-P
foi uma novidade completamente nova para mim, estou felizmente me cumprimentando há anos e usando apenas -E
... tantos anos perdidos ! - Nota para si mesmo: releia as páginas de manual como uma coisa regular (ainda mais!), Você nunca digere opções e opções suficientes.
grep
não há suporte -P
, mas se você usar, egrep
poderá usar o .*?
padrão para obter o mesmo resultado. egrep -o 'start.*?end' text.html
-P
mas -E
chamaria, egrep
portanto, as sugestões sugeridas .*?
funcionam perfeitamente.
Atualmente, o .*?
único funciona perl
. Não tenho certeza de qual seria a sintaxe regexp estendida grep equivalente. Felizmente, você pode usar a sintaxe perl com o grep para grep -P
que funcione, mas grep -E
que é o mesmo egrep
que não funcionaria (seria ganancioso).
Veja também: http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html
grep -P
não funciona no GNU grep 2.9 - apenas tentei (isso não acontecer erro, apenas silenciosamente não se aplica a ?
Intertestly nem o. Não classe por exemplo:env|grep '[^\=]*\='
grep -P
opção ou pgrep
comando no Darwin / OS X 10.8 Mountain Lion, mas egrep
funciona muito bem.
pgrep
comando na minha caixa do OS X 10.9, mas é um programa completamente diferente cujo objetivo é "localizar ou sinalizar processos por nome".
Meu grep que funciona depois de experimentar coisas neste segmento:
echo "hi how are you " | grep -shoP ".*? "
Apenas certifique-se de acrescentar um espaço a cada uma das suas linhas
(O meu era uma pesquisa linha por linha para cuspir palavras)
-shoP
nice :) mnemônico
echo "bbbbb" | grep -shoP 'b.*?b'
é um pouco de uma experiência de aprendizado. A única coisa que funcionou para mim em termos de explicitamente preguiçoso também.
grep
Para correspondência não gananciosa, grep
você pode usar uma classe de personagem negada. Em outras palavras, tente evitar caracteres curinga.
Por exemplo, para buscar todos os links para arquivos JPEG no conteúdo da página, você usaria:
grep -o '"[^" ]\+.jpg"'
Para lidar com várias linhas, canalize a entrada xargs
primeiro. Para desempenho, use ripgrep
.
A resposta curta está usando a próxima expressão regular:
(?s)<car .*? model=BMW .*?>.*?</car>
Uma resposta (pouco) mais complicada é:
(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>
Isso possibilitará a correspondência de car1 e car2 no texto a seguir
<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
Desculpe, estou com 9 anos de atraso, mas isso pode funcionar para os telespectadores em 2020.
Então, suponha que você tenha uma linha como "Hello my name is Jello"
. Agora você deseja encontrar as palavras que começam 'H'
e terminam 'o'
com qualquer número de caracteres no meio. E não queremos linhas, apenas palavras. Então, para isso, podemos usar a expressão:
grep "H[^ ]*o" file
Isso retornará todas as palavras. A maneira como isso funciona é o seguinte: Permitirá todos os caracteres em vez do caractere de espaço entre eles, desta forma, podemos evitar várias palavras na mesma linha.
Agora você pode substituir o caractere de espaço por qualquer outro caractere que desejar. Suponha que a linha inicial era "Hello-my-name-is-Jello"
, então você pode obter palavras usando a expressão:
grep "H[^-]*o" file
Eu sei que é um post meio morto, mas notei que isso funciona. Ele removeu a limpeza e a limpeza da minha saída.
> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20