Bash: Estrarre occorrenze multiple di una regex da una linea di testo

Per estrarre occorrenze multiple di una regex da una riga di testo (ad esempio le URL da un file HTML) bisogna ricorrere ad un artificio.

Infatti il pattern “.*” è greedy, cioè va a prendere la più grande occorrenza che trova, non solamente la prima ! Ad esempio “http.*jpg” non trova il primo file, ma tutta la stringa racchiusa tra il primo “http” trovato e l’ ultimo “jpg” trovato.

L’ artificio è il seguente: spezzare la riga di testo con un carattere univoco, ed usarlo come “segnaposto” per la stringa da estrarre.
Il carattere univoco è il “newline”: \n.

Vediamo i singoli passi:

# aggiungere il carattere univoco all' inizio della stringa
# notare il simbolo &
sed 's/http:/\n&/g'
# poi eliminare tutti i caratteri diversi da \n
# notare il [^\n]* tra http e jpg !!!
# è questo ad aggirare il comportamento greedy !!!
sed 's/[^\n]*\n\(http[^\n]*\.jpg\)[^\n]*/\1\n/g'

# METTENDO TUTTO INSIEME:
cat textstring.txt | sed 's/http:/\n&/g;s/[^\n]*\n\(http[^\n]*\.jpg\)[^\n]*/\1\n/g'

Con python è più semplice: basta usare il “?” per modificare il comportamento del pattern “.*” in non-greedy e poi usare il comando findall per trovare tutte le occorrenze in una lista

import re
# notare il "?" che modifica in non-greedy:
regex=re.compile("http.*?\.jpg")
results=regex.findall(file-string)

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...