2012-12-15 8 views
5

Ho contenuto HTML memorizzato in una tabella di database. in quel contenuto html voglio sostituire "ALCUNE PAROLE" con un tag link. Ma se "ALCUNE PAROLE" è già all'interno di un tag di collegamento dovrei ometterlo ..php espressione regolare per sostituire "alcune parole" con un tag link, ma dovrebbe escludere "alcune parole" all'interno dei tag di collegamento

ad es.
Il contenuto

<p>Lorem ipsum dolor SOME WORDS, consectetur adipiscing elit. <a href="http://example.com">SOME WORDS</a> elementum pharetra velit at cursus. Quisque blandit, nibh at eleifend ullamcorper</p> 

L'uscita dovrebbe essere

<p>Lorem ipsum dolor <a href="http://someurl">SOME WORDS</a>, consectetur adipiscing elit. <a href="http://example.com">SOME WORDS</a> elementum pharetra velit at cursus. Quisque blandit, nibh at eleifend ullamcorper</p> 

come si può vedere, si dovrebbe escludere testi legame esistente in caso di sostituzione.

Alcune indicazioni per entrare nella giusta direzione sono molto apprezzate.

+2

Non usare le espressioni regolari, utilizzare un parser HTML come DOMDocument –

+0

Try - http://www.solmetra.com /scripts/regex/index.php - e - http://weblogtoolscollection.com/regex/regex.php - e qualche altra schifezza. – qooplmao

+1

Ricorda quella ragazza dal ring? Ha provato a usare espressioni regolari per elaborare anche l'HTML, e vedere cosa le è successo! –

risposta

3

questo è come si potrebbe risolvere utilizzando DOMDocument invece di espressioni regolari:

$contents = <<<EOS 
<p>Lorem ipsum dolor SOME WORDS, consectetur adipiscing elit. <a href="http://example.com">SOME WORDS</a> elementum pharetra velit at cursus. Quisque blandit, nibh at eleifend ullamcorper</p> 
EOS; 

$doc = new DOMDocument; 
libxml_use_internal_errors(true); 
$doc->loadHTML($contents); 
libxml_clear_errors(); 

$xp = new DOMXPath($doc); 

// find all text nodes 
foreach ($xp->query('//text()') as $node) { 
     // make sure it's not inside an anchor 
     if ($node->parentNode->nodeName !== 'a') { 
       $node->nodeValue = str_replace(
        'SOME WORDS', 
        'SOME OTHER WORDS', 
        $node->nodeValue 
       ); 
     } 
} 
// DOMDocument creates a full document and puts your fragment inside a body tag 
// So we enumerate the children and save their HTML representation 
$body = $doc->getElementsByTagName('body')->item(0); 
foreach ($body->childNodes as $node) { 
     echo $doc->saveHTML($node); 
} 
+0

grazie .. questo ha risolto il problema .. Non ho pensato di usare un parser html .. – sanandrl

+0

Prego.I parser HTML sono un ottimo argomento da studiare :) –

0

Questo dovrebbe fare il trucco.

Proprio il check-in regex se qualche PAROLE è circondato da tag

preg_replace('/[^>]SOME WORDS[^<]/','<a href="http://someurl">SOME WORDS</a>',$str); 
+2

questo si interromperà in qualcosa tipo: here are SOME WORDS for you

1

semplice regex funziona solo se è la frase esatta e all'interno del link, senza altri simboli o parole. È possibile scorrere tutte le occorrenze di SOME WORDS per verificare se si trovano all'interno di un collegamento calcolando il numero di volte in cui un tag di collegamento di apertura e chiusura è stato presente prima dell'occorrenza. Prova di questo codice:

$str = '<p>Lorem ipsum dolor SOME WORDS, consectetur adipiscing elit. <a href="http://example.com">SOME WORDS</a> elementum pharetra velit at cursus. Quisque blandit, nibh at eleifend ullamcorper</p>'; 
echo 'Before:' . $str; 
$str_lc = strtolower($str); 
$phrase = 'SOME WORDS'; 
$link = '<a href="http://someurl">SOME WORDS</a>'; 
$offset = 0; 
while($position = strpos($str, $phrase, $offset)) 
{ 
    if (substr_count($str_lc, "<a", 0, $position) <= substr_count($str_lc, "</a>", 0, $position)) { 
     $str = substr_replace($str, $link, $position, strlen($phrase)); 
     $str_lc = strtolower($str); 
     $offset = $position + strlen($link) - strlen($phrase); 
    } else { 
     $offset = $position + 1; 
    } 
} 
echo 'After:' . $str; 
1

Se avete spazio per 3 linee questa sarebbe una scommessa sicura:

$text=preg_replace('~<a(.*)(SOME WORDS)(.*)</a>~','<a$1PLACEHOLDER$3</a>',$text); 
$text=preg_replace('~SOME WORDS~','REPLACEMENT WORDS',$text); 
$text=preg_replace('~PLACEHOLDER~','SOME WORDS',$text); 

Si userà un testo segnaposto/tag/qualunque cosa in modo da non sostituire un link contenuto (nel caso ce ne sia uno).

Problemi correlati