Risposte:
Stai cercando una partita non golosa (o pigra). Per ottenere una corrispondenza non avida nelle espressioni regolari è necessario utilizzare il modificatore ?
dopo il quantificatore. Ad esempio è possibile passare .*
a .*?
.
Per impostazione predefinita grep
non supporta modificatori non avidi, ma è possibile utilizzare grep -P
per utilizzare la sintassi Perl.
.
di abbinare le nuove righe è chiamata modalità DOTALL o single-line ; Ruby è l'unico che lo chiama multilinea . Negli altri gusti, multilinea è la modalità che consente alle ancore ( ^
e $
) di abbinarsi ai confini della linea. Ruby non ha una modalità equivalente perché in Ruby funzionano sempre in questo modo.
-P
è stato completamente nuovo per me, sto felicemente svanendo da anni, e usando solo -E
... tanti anni sprecati! - Nota per sé: rileggi le pagine Man come una cosa (ancora di più!) Normale, non digerisci mai abbastanza opzioni e opzioni.
grep
non supporta -P
, ma se si utilizza egrep
è possibile utilizzare il .*?
modello per ottenere lo stesso risultato. egrep -o 'start.*?end' text.html
-P
ma -E
chiamerebbe egrep
quindi il suggerito .*?
funziona bene.
In realtà l' .*?
unico funziona perl
. Non sono sicuro di quale sarebbe la sintassi della regexp estesa grep equivalente. Fortunatamente puoi usare la sintassi perl con grep, quindi grep -P
funzionerebbe ma grep -E
che è lo stesso che egrep
non funzionerebbe (sarebbe avido).
Vedi anche: http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html
grep -P
non funziona in GNU grep 2.9 - l'ho appena provato (non commette errori, silenziosamente non applica il ?
. Intertestamente né la classe non es.:env|grep '[^\=]*\='
grep -P
opzione o pgrep
comando in Darwin / OS X 10.8 Mountain Lion, ma egrep
funziona alla grande.
pgrep
comando sulla mia casella OS X 10.9, ma è un programma completamente diverso il cui scopo è "trovare o segnalare i processi per nome".
Il mio grep che funziona dopo aver provato cose in questo thread:
echo "hi how are you " | grep -shoP ".*? "
Assicurati di aggiungere uno spazio a ciascuna delle tue linee
(La mia era una ricerca riga per riga per sputare le parole)
-shoP
nice mnemonic :)
echo "bbbbb" | grep -shoP 'b.*?b'
è un po 'di esperienza di apprendimento. L'unica cosa che ha funzionato anche per me in termini di esplicitamente pigro.
grep
Per una partita non golosa grep
potresti usare una classe di personaggi negata. In altre parole, cerca di evitare i caratteri jolly.
Ad esempio, per recuperare tutti i collegamenti ai file jpeg dal contenuto della pagina, utilizzare:
grep -o '"[^" ]\+.jpg"'
Per gestire più righe, reindirizzare prima l'input xargs
. Per prestazioni, utilizzare ripgrep
.
La risposta breve sta usando la seguente espressione regolare:
(?s)<car .*? model=BMW .*?>.*?</car>
Una (piccola) risposta più complicata è:
(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>
Ciò consentirà di abbinare car1 e car2 nel seguente testo
<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
Mi dispiace, sono in ritardo di 9 anni, ma questo potrebbe funzionare per gli spettatori nel 2020.
Quindi supponiamo di avere una linea come "Hello my name is Jello"
. Ora vuoi trovare le parole che iniziano con 'H'
e finiscono con 'o'
, con un numero qualsiasi di caratteri in mezzo. E non vogliamo linee, vogliamo solo parole. Quindi per questo possiamo usare l'espressione:
grep "H[^ ]*o" file
Questo restituirà tutte le parole. Il modo in cui funziona è questo: consentirà a tutti i caratteri invece di spazio tra i caratteri in mezzo, in questo modo possiamo evitare più parole nella stessa riga.
Ora puoi sostituire il carattere spazio con qualsiasi altro personaggio che desideri. Supponiamo che la riga iniziale fosse "Hello-my-name-is-Jello"
, quindi puoi ottenere parole usando l'espressione:
grep "H[^-]*o" file
So che è un po 'un post morto ma ho appena notato che funziona. Ha rimosso sia la pulizia che la pulizia dal mio output.
> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20