# Regular expressions - lookbehind

**URL:** <https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906>\
**Category:** IT\
**Created:** [March 23, 2007, 6:07pm UTC](https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906 "2007-03-23T18:07:54Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![esox\_ch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/4da419/32.png) [@esox\_ch](https://www.ruby-forum.com/u/esox_ch)\
**Post date:** [March 23, 2007, 6:07pm UTC](https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906/1 "2007-03-23T18:07:54Z")

</div>

Ciao a tutti

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

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? 🙂 )

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

---

<div class="post-metadata">

**Author:** ![esox\_ch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/4da419/32.png) [@esox\_ch](https://www.ruby-forum.com/u/esox_ch)\
**Post date:** [March 23, 2007, 8:54pm UTC](https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906/2 "2007-03-23T20:54:11Z")

</div>

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 [サービス終了のお知らせ](http://www.geocities.jp/kosako3/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://www.gabrielelana.it/archives/15)  
[http://code.google.com/p/roxi/](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](http://www.gabrielelana.it) - Agile methodologies and Programming  
[http://www.xpug.it](http://www.xpug.it) - italian eXtreme Programming User Groups**

---

<div class="post-metadata">

**Author:** ![esox\_ch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/4da419/32.png) [@esox\_ch](https://www.ruby-forum.com/u/esox_ch)\
**Post date:** [March 24, 2007, 4:52pm UTC](https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906/3 "2007-03-24T16:52:54Z")

</div>

Grazie per la celere risposta

> o usi Oniguruma [サービス終了のお知らせ](http://www.geocities.jp/kosako3/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 😉

jeko

---

<div class="post-metadata">

**Author:** ![esox\_ch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/4da419/32.png) [@esox\_ch](https://www.ruby-forum.com/u/esox_ch)\
**Post date:** [March 24, 2007, 5:14pm UTC](https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906/4 "2007-03-24T17:14:58Z")

</div>

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 😉

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, … 🙂

---

<div class="post-metadata">

**Author:** ![esox\_ch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/4da419/32.png) [@esox\_ch](https://www.ruby-forum.com/u/esox_ch)\
**Post date:** [March 26, 2007, 10:44am UTC](https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906/5 "2007-03-26T10:44:54Z")

</div>

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? 🙂 )

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

---

<div class="post-metadata">

**Author:** ![esox\_ch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/4da419/32.png) [@esox\_ch](https://www.ruby-forum.com/u/esox_ch)\
**Post date:** [March 23, 2007, 10:56pm UTC](https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906/6 "2007-03-23T22:56:26Z")

</div>

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?  
> > 🙂 )

> [Google Code Archive - Long-term storage for Google Code Project Hosting.](http://code.google.com/p/roxi/)  
> 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 😛**

 

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

---

<div class="post-metadata">

**Author:** ![esox\_ch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/4da419/32.png) [@esox\_ch](https://www.ruby-forum.com/u/esox_ch)\
**Post date:** [March 27, 2007, 10:46pm UTC](https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906/7 "2007-03-27T22:46:06Z")

</div>

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

> Grazie per la celere risposta
> 
> > o usi Oniguruma [サービス終了のお知らせ](http://www.geocities.jp/kosako3/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 🙂  
[http://rubyforge.org/forum/forum.php?forum\_id=13049](http://rubyforge.org/forum/forum.php?forum_id=13049)

enjoy 🙂

Francesco

---

<div class="post-metadata">

**Author:** ![esox\_ch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/4da419/32.png) [@esox\_ch](https://www.ruby-forum.com/u/esox_ch)\
**Post date:** [March 28, 2007, 10:38am UTC](https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906/8 "2007-03-28T10:38:34Z")

</div>

Wow ma è un notizione! Grazie 1000 🙂

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

jeko

---

<div class="post-metadata">

**Author:** ![esox\_ch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/4da419/32.png) [@esox\_ch](https://www.ruby-forum.com/u/esox_ch)\
**Post date:** [March 26, 2007, 11:09am UTC](https://www.ruby-forum.com/t/regular-expressions-lookbehind/89906/9 "2007-03-26T11:09:58Z")

</div>

> 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! 🙂

jeko
