Regular expressions - lookbehind

Ciao a tutti

Mi rivolgo in particolare ai maestri dell’antica arte delle regular
expressions (giovà’? :slight_smile: )

Ho scoperto con sommo stupore e profonda costernazione che ruby non
supporta i lookbehind nelle regexp

Io volevo fare una regular che mi permettesse, in un xhtml, di togliere
i tag span e strong, aperti e chiusi, solo se contenuti all’interno di
un tag caption (cosa ti portano a fare i clienti, eh? :slight_smile: )

La regular, molto pittoresca, che mi sono fatto è

/(?<=.?)(</(span|strong)>)(?=.*?</caption>)/i

E speravo in ruby di cavarmela con un

valore.gsub!(/(?<=.?)(</(span|strong)>)(?=.*?</caption>)/i,
‘’)

Ma ottengo un simpatico errore, che mi ha fatto indagare e scoprire la
mancanza del supporto di questo tipo di regex

Esiste forse un workaround noto per non usare i lookbehind (?<=…) e
ottenere lo stesso risultato?

Bella pe voi

jeko

venerdi 23 marzo 2007, alle 18:06, il navigatore Stefano G.
scrisse:

valore.gsub!(/(?<=.?)(</(span|strong)>)(?=.*?</caption>)/i, ‘’)

Ma ottengo un simpatico errore, che mi ha fatto indagare e scoprire la mancanza del supporto di questo tipo di regex

Esiste forse un workaround noto per non usare i lookbehind (?<=…) e ottenere lo stesso risultato?

o usi Oniguruma サービス終了のお知らせ

oppure questo potrebbe funzionare

output = input.gsub(/()(.?)(</caption>)/m) do
before, after = $1, $3
substituted = $2.gsub(/.
?</span>|.*?</strong>/m, ‘’)
before + substituted + after
end

in alternativa se fosse xhtml valido con ROXI
http://www.gabrielelana.it/archives/15
http://code.google.com/p/roxi/

potresti fare una cosa del tipo

output = XDocument.string(input).update do
select(‘//span[ancestor::caption] | //strong[ancestor::caption]’) do |
node |
node.delete
end
end.to_s

cosa che considererei decisamente piu’ sicura in quanto non so se la
prima soluzione considera tutti i possibili corner case, la seconda
invece e’ sicuramente corretta e decisamente piu’ leggibile nelle
intenzioni (rimuovi tutti gli ‘span’ e gli ‘strong’ figli di
‘caption’)


Gabriele L.
contact me at info at gabrielelana dot it
http://www.gabrielelana.it - Agile methodologies and Programming
http://www.xpug.it - italian eXtreme Programming User Groups

Grazie per la celere risposta

o usi Oniguruma サービス終了のお知らせ

Ho visto oniguma appena dopo aver mandato la mail… Purtroppo sono in
un ambiente di produzione abbastanza delicato, la stabilità è
importantissima e ricompilare ruby non è una cosa che posso fare tanto
alla leggera… Ad ogni modo sto scaricando oniguruma e lo inizio a
provare da subito! Sapere che sarà integrato nelle prossime release di
ruby è comunque un sollievo…

oppure questo potrebbe funzionare …

in alternativa se fosse xhtml valido con ROXI

Si, è xhtml valido fresco fresco di tidy, avevo pensato anche ad hpricot
ma non volevo appesantire l’applicazione con altre librerie: si tratta
di ripulire circa 300.000 unità di testo e le performances e
semplicità dell’applicaizone sono molto importanti… Ed in ogni caso la
mia esigenza è leggermente diversa: io non devo eliminare gli span e gli
strong con il loro contenuto, devo eliminare fisicamente i tag span e
strong e lasciare il contenuto intatto… Per questo la strada delle
regular era la piu semplice… “Purtroppo” quella regular in .NET
funziona, e non sai quanto mi brucia :wink:

jeko

sabato 24 marzo 2007, alle 16:52, il navigatore Stefano G.
scrisse:

Si, e’ xhtml valido fresco fresco di tidy, avevo pensato anche ad
hpricot ma non volevo appesantire l’applicazione con altre librerie:
si tratta di ripulire circa 300.000 unita’ di testo e le performances
e semplicita’ dell’applicaizone sono molto importanti… Ed in ogni
caso la mia esigenza e’ leggermente diversa: io non devo eliminare
gli span e gli strong con il loro contenuto, devo eliminare
fisicamente i tag span e strong e lasciare il contenuto intatto…
Per questo la strada delle regular era la piu semplice…
“Purtroppo” quella regular in .NET funziona, e non sai quanto mi
brucia :wink:

bhe dai, te la cavi con poco di piu’

output = input.gsub(/.*?</caption>/m) do | within_caption |
within_caption.gsub(/</?(?:span|strong)>/, ‘’)
end

P.S. tra l’altro oniguruma supporta anche una cosa che ho sempre
invidiato alle regex di .NET, i gruppi con nome: si potranno dare nomi
ai submatch in modo da poter avere dei riferimenti piu’ significativi
di \1, \2, … :slight_smile:

Stefano G. wrote:

Ciao a tutti

Io volevo fare una regular che mi permettesse, in un xhtml, di togliere i tag span e strong, aperti e chiusi, solo se contenuti all’interno di un tag caption (cosa ti portano a fare i clienti, eh? :slight_smile: )

Ciao,

Anche secondo me ti conviene parsarlo come xml. Usare le regexp per
‘capire’ l’html e’ soggetto ad errori.
Metti che il tag iniziale e’ dentro un commento?

bau

venerdi 23 marzo 2007, alle 20:47, il navigatore Gabriele L. scrisse:

Io volevo fare una regular che mi permettesse, in un xhtml, di
togliere i tag span e strong, aperti e chiusi, solo se contenuti
all’interno di un tag caption (cosa ti portano a fare i clienti, eh?
:slight_smile: )

Google Code Archive - Long-term storage for Google Code Project Hosting.
prima soluzione considera tutti i possibili corner case
per esempio

input = “insidedeepinside

darebbe un output del tipo

output == “”

potremmo optare per una soluzione greedy assumendo che comunque
all’interno di caption tuttli gli span sono accoppiati e devono essere
tolti

output = input.gsub(/()(.?)(</caption>)/m) do
before, after = $1, $3
substituted = $2.gsub(/.
</span>|.*</strong>/m, ‘’)
before + substituted + after
end

ma fallirebbe con un input del tipo

input = “insidekeepinside

dovrebbe essere

output == “keep”

invece essendo greedy il moltiplicatore all’interno degli span

output == “”

NOTA: non te la cavi neanche con i lookbehind, in quando quella che
stai cercando di riconoscere non e’ una stringa riconoscibile da una
grammatica di tipo 3 (grammatiche costruibili con le espressioni
regolari) (se non sbaglio dimostrabile facilmente con il “pumping
lemma”)

la seconda invece e’ sicuramente corretta e decisamente piu’
leggibile nelle intenzioni (rimuovi tutti gli ‘span’ e gli ‘strong’
figli di ‘caption’)

mi sono accorto che con ROXI c’e’ una soluzione ancora piu’ semplice,
mi ero dimenticato che avevo creato uno shortcut :stuck_out_tongue:

output = XDocument.string(input).update do
remove(‘//span[ancestor::caption] | //strong[ancestor::caption]’)
end.to_s

On Saturday 24 March 2007 16:52, Stefano G. wrote:

Grazie per la celere risposta

o usi Oniguruma サービス終了のお知らせ

Ho visto oniguma appena dopo aver mandato la mail… Purtroppo sono in un
ambiente di produzione abbastanza delicato, la stabilità è importantissima
e ricompilare ruby non è una cosa che posso fare tanto alla leggera… Ad
ogni modo sto scaricando oniguruma e lo inizio a provare da subito! Sapere
che sarà integrato nelle prossime release di ruby è comunque un
sollievo…

Ne ho appena parlato su irc con Gabriele Renzi, non serve ricompilare
ruby
perchè ci sono i bindings per oniguruma :slight_smile:
http://rubyforge.org/forum/forum.php?forum_id=13049

enjoy :slight_smile:

Francesco

Wow ma è un notizione! Grazie 1000 :slight_smile:

Vi premio con un post che forse non vi serve ma è il frutto delle mie
ricerche di ieri :wink:

jeko

bhe dai, te la cavi con poco di piu’

output = input.gsub(/.*?</caption>/m) do | within_caption |
within_caption.gsub(/</?(?:span|strong)>/, ‘’) end

È la soluzione che ho usato… Grazie! :slight_smile:

jeko