Newsgroup: it.comp.www.php
Titolo: problemino espressione regolare

ciao a tutti.
ho un piccolo problema con una espressione regolare.
funziona bene, ma quando trova tag doppi va in tilt e ne rimpiazza solo 1:
ad esempio:
$testo="[QUOTE]ciao[QUOTE]ciao2[/QUOTE][/QUOTE]";
$testo=ereg_replace("/\[QUOTE\](.+?)\[\/QUOTE\]/s","<b>citazione:<b><br>$1<br>",$testo);
me lo trasforma cosi:
<b>citazione</b><br>[QUOTE]ciao2<br>[/QUOTE]
invece di
<b>citazione</b><br>ciao1<b>citazione</b><br>ciao2<br><br>
forse c'è qualcosa di sbagliato nell'espressione regolare? 

cicciolino ha scritto:

Cosi' ti va bene? ciao.
$testo="[QUOTE]ciao1[QUOTE]ciao2[/QUOTE][/QUOTE]";
$safeMaxCount = 50; // di sicurezza
for($i = 0; $i < $safeMaxCount; $i++)
{       $t = preg_replace(
		"~\[QUOTE\]((?(?!\[/?QUOTE\]).)*)\[/QUOTE\]~s",
		"<b>citazione:</b><br>$1<br>",
		$testo
	);
         if($t == $testo)
                 break;
         $testo = $t;
}
echo $testo;
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

 echo $testo;
grazie funziona, ma sinceramente non riesco a capire a cosa serve il for....
comunque, quel /?quote immezzo all'esperssione regolare dice di non 
considerare se ne apre un altro di quote ?
comunque grazie. 

 comunque grazie. 
Mi sembrava che ti servisse un qualcosa che risolvesse i tag 
[QUOTE][/QUOTE] stettamente presi per coppia corrispondente, giusto?
Quindi, se nidificati, una soluzione e' quella di risolvere mano a mano 
quelli piu' interni fino a completamento della stringa "testo" (ecco 
perche' il ciclo for).
La regular expression si occupa, per ogni ciclo, di trovare e risolvere 
le coppie di tag non nidificati di [QUOTE]...[/QUOTE]; ovvero che non 
hanno al loro interno un altro tag [QUOTE], aperto o chiuso.
Dentro l'espressione regolare c'e una 'if' "(?(condition)yes-pattern)" 
con dentro una asserzione negativa "(?!" che ne incasina un po' le lettura.
Per vedere come funziona usa una stringa iniziale + complessa ed una 
stringa di replace + leggibile. Tipo:
<?php
$testo="[QUOTE]aaa[QUOTE]bbb[/QUOTE]ccc[QUOTE]ddd[QUOTE]eee[/QUOTE]fff[QUOTE]ggg[QUOTE]hhh[/QUOTE]iii[/QUOTE]lll[/QUOTE][/QUOTE]";
echo "TESTO: $testo\n";
$safeMaxNestedQuote=50;
for($i = 1; $i <= $safeMaxNestedQuote; $i++)
{       $t = preg_replace(
                 "~\[QUOTE\]((?(?!\[/?QUOTE\]).)*)\[/QUOTE\]~s",
                 "<Q$i>$1</Q$i>",
                 $testo
         );
         if($t == $testo)
                 break;
         $testo = $t;
         echo "PASSAGGIO $i: $testo\n";
}
echo "TESTO FINALE: $testo\n";
?>
...dopo 4 passaggi, dovrebbe stampare:
TESTO: 
[QUOTE]aaa[QUOTE]bbb[/QUOTE]ccc[QUOTE]ddd[QUOTE]eee[/QUOTE]fff[QUOTE]ggg[QUOTE]hhh[/QUOTE]iii[/QUOTE]lll[/QUOTE][/QUOTE]
PASSAGGIO 1: 
[QUOTE]aaa<Q1>bbb</Q1>ccc[QUOTE]ddd<Q1>eee</Q1>fff[QUOTE]ggg<Q1>hhh</Q1>iii[/QUOTE]lll[/QUOTE][/QUOTE]
PASSAGGIO 2: 
[QUOTE]aaa<Q1>bbb</Q1>ccc[QUOTE]ddd<Q1>eee</Q1>fff<Q2>ggg<Q1>hhh</Q1>iii</Q2>lll[/QUOTE][/QUOTE]
PASSAGGIO 3: 
[QUOTE]aaa<Q1>bbb</Q1>ccc<Q3>ddd<Q1>eee</Q1>fff<Q2>ggg<Q1>hhh</Q1>iii</Q2>lll</Q3>[/QUOTE]
PASSAGGIO 4: 
<Q4>aaa<Q1>bbb</Q1>ccc<Q3>ddd<Q1>eee</Q1>fff<Q2>ggg<Q1>hhh</Q1>iii</Q2>lll</Q3></Q4>
TESTO FINALE: 
<Q4>aaa<Q1>bbb</Q1>ccc<Q3>ddd<Q1>eee</Q1>fff<Q2>ggg<Q1>hhh</Q1>iii</Q2>lll</Q3></Q4>
(il numero in <Qn> indica il passaggio)
Ciao


 dentro una asserzione negativa "(?!" che ne incasina un po' le lettura.
ok adesso è tutto chiaro.
non c'ero neancora arrivato alla condizione "if" nelle regexpr.
è per quello che non ci capivo tanto.
grazie
ps: ho provato con una quarantina di quote nidificati e funziona alla 
grande.
ciao