Newsgroup: it.comp.www.php
Titolo: Espressioni regolari. Non ce ne vengo fuori!!!!

Ho un problema con le espressioni regolari e purtroppo, nonostante abbia 
studiato per bene le pagine sul sito di  
php.net
, non sono ancora 
riuscito a trovare una soluzione definitiva.
Ho una pagina ed una serie di termini. Con termine intendo una parola o 
una frase di massimo 4 o 5 parole. Devo mettere un link ad ogni termine 
presente nella pagina. Alcuni di questo termini sono parte di altri.
Ad esempio due termini sono questi:
Ranger
Ranger One
Un esempio del testo della pagina e`:
"La forma Minbari di Ranger One, il titolo dato al capo dei Ranger in 
tempo di pace."
In questo esempio bisogna mettere un link a "Ranger One" ed un altro a 
"Ranger" ma se elaboro prima "Ranger" mi prende il primo della frase che 
invece spetterebbe all'altro termine.
La mia idea e` questa. Faccio un sort dei termini per dimensione in 
caratteri cosi` quelli piu` lunghi verranno processati prima. Poi dovro` 
evitare che i termini gia` linkati non lo possano piu` essere.
Il primo giro funziona ma al secondo c'e` un problema.
Il link al primo termine diventa:
<a href="index.php?ref=Ranger One">Ranger One</a>
Pero` la parola "Ranger" del link viene riconosciuta come valida e ci 
mette un altro link dentro il link stesso:
La frase che ne esce e` chiaramente sbagliata:
"La forma Minbari di "<a href="index.php?ref<a 
href="index.php?ref=Ranger">Ranger</a>One">Ranger One</a>", il      
titolo dato al capo dei Ranger in tempo di pace."
C'e` anche un altro problema, mi ha tolto un carattere prima e uno dopo 
la sostituzione.
Questa e` l'istruzione che uso (l'ho semplificata per una maggiore 
chiarezza):
preg_replace(
  '/[^<a*>*]Ranger[^*<\/a>]/i',
  '<a href="index.php?ref=Ranger">Ranger</a>',
  'La forma Minbari di "<a href="index.php?ref=Ranger One">Ranger
   One</a>", il titolo dato al capo   dei Ranger in tempo di pace.',
  1 );
Se il primo link lo cambio e ci metto:
<a href="index.php?ref=link_alla_pagina">
allora funziona perfettamente, ma non e` quello che mi serve.
Il risultato finale che vorrei ottenere e` questo:
"La forma Minbari di "<a href="index.php?ref=Ranger One">Ranger 
One</a>", il titolo dato al capo dei <a 
href="index.php?ref=Ranger">Ranger</a> in tempo di pace."
Questo e` un esempio semplice, ma i termini e quindi le pagine con cui 
devo lavorare saranno circa 2000.
Ringrazio chiunque mi dia un aiuto.
-- 
|- Massimo ;-) ---> 
http://maq.altervista.org
 <-----|(o-  POWERED |
|- BABYLON 5 -----> 
http://babylon5.altervista.org
 <|(/)_ BY LINUX|
|- STARGATE ------> 
http://sg1screw.altervista.org
 <|And the sky  |
|WHAT DO YOU WANT?> 
http://morden.deviantart.com
 <--|full of stars|

 mette un altro link dentro il link stesso:
Potresti aggirare il problema: nel link anzichè mettere la parola metti 
un id corrispondente, salvando le corrispondenze in una tabella di 
lookup.

 di lookup.
Si, lo so, ed e` un'alternativa sicuramente valida, pero` preferisco 
metterci direttamente la parola.
Per ora ho risolto con un codice molto meno elegante che a suon di 
strpos va a cercare la parola da linkare.
Con i pochi termini che ho ora le prestazioni sono molto buone, vedremo 
i decadimenti quando aumenteranno i termini. Arriveranno fino a circa 
2000.
In ogni caso quello che vorrei fare io si puo` con le espressioni 
regolari oppure no? Vorrei evitare di perdere tempo con cose 
impossibili.


 regolari oppure no?
Probabilmente si può fare di meglio, il mio è solo un workaround.
Allora... sort-i le parole in base alla lunghezza (decrescente).
Ogni volta che match-i una parola, gli sostituisci un riferimento
temporaneo, ad es. '-#0#-'. E inserisci in un array il reale sostituto:
 
    $arr[] = '<a href=...>Ranger One</a>';
Alla fine, ti ritroverai con:
    $str == "La forma Minbari di -#0#-, il titolo dato
             al capo dei -#1#- in tempo di pace.";
    $arr == array ( 0 => '<a href=...>Ranger One</a>',
                    1 => '<a href=...>Ranger</a>'      );
Ti basterà quindi ciclare l'array e sostituire col sostituto reale:
    foreach ($arr as $i => $link)
        $str = str_replace("-#$i#-", $link, $str);
Ovviamente, dovresti controllare che '/-#\d?#-/' non esista nella
stringa iniziale. Solo in questo caso ti convengono le regex.
Ciao
Maverick
ps. non ho testato il codice, e non so quanto sarà performante come
workaround: invece di fare n replace ne dovrai fare 2n. Ad ogni modo, se
lo implementi e fai delle prove di benchmark, fammi sapere come va. ;-)
-- 
«Che non siete più liberi di non avere una casa con letto per dormire.
 Lavorate voi - schiavi dei soldi - che non sentite la puzza della
 schiavitù!» (a Mario di Monte Mario, Roma) # 
http://libre.netsons.org/