2010-06-29 4 views
0

J'ai une expression régulière qui regarde le contenu html pour certains mots-clés qui fonctionnaient, mais qui échoue maintenant et je ne comprends pas pourquoi. (L'expression régulière est venue de this thread.)l'expression régulière find-and-replace-in-html échoue

$find = '/(?![^<]+>)(?<!\w)(' . preg_quote($t['label']) . ')\b/s'; 
$text = preg_replace_callback($find, 'replaceCallback', $text); 

function replaceCallback($match) { 
     if (is_array($match)) { 
      $htmlVersion = $match[1]; 
      $urlVersion = urlencode($htmlVersion); 
      return '<a class="tag" rel="tag-definition" title="Click to know more about ' . $htmlVersion . '" href="?tag=' . $urlVersion . '">' . $htmlVersion . '</a>'; 
     } 
     return $match; 
    } 

Les points de message d'erreur à l'appel preg_replace_callback et dit:

Warning: preg_replace_callback() [function.preg-replace-callback]: Unknown modifier 't' in /frontend.functions.php on line 43 
+3

HTML est pas une langue régulière des expressions régulières de façon peuvent ne pas être le meilleur outil ici. –

+4

Vous ne devez pas utiliser d'expressions régulières pour analyser html. Voir ici: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – Oded

+2

Va-t-il jamais s'arrêter? – Gordon

Répondre

0

S'il vous plaît noter: c'est pas une tentative de fournir une solution pour l'expression rationnelle. C'est juste ici pour montrer combien il est difficile (oserais-je dire impossible) de créer une regex qui va analyser avec succès HTML. Même un XHTML bien structuré serait difficile à cerner, mais un HTML mal structuré est un non-lieu pour les expressions régulières.

Je suis d'accord à 100% que l'utilisation d'expressions régulières pour tenter l'analyse HTML est une très mauvaise idée. Le code suivant utilise la fonction fournie pour analyser certaines balises HTML simples. Il trébuche sur sa deuxième tentative quand il trouve la balise HTML imbriqué <em>Test<em>:

$t['label'] = 'Test'; 
$text = '<p>Test</p>'; 

$find = '/(?![^<]+>)(?<!\w)(' . preg_quote($t['label']) . ')\b/s'; 
$text = preg_replace_callback($find, 'replaceCallback', $text); 

echo "Find: $find\n"; 
echo 'Quote: ' . preg_quote($t['label']) . "\n"; 
echo "Result: $text\n"; 

/* Returns: 

Find: /(?![^<]+>)(?<!\w)(Test)\b/s 
Quote: Test 
Result: <p><a class="tag" rel="tag-definition" title="Click to know more about Test" href="?tag=Test">Test</a></p> 

*/ 

$t['label'] = '<em>Test</em>'; 
$text = '<p>Test</p>'; 

$find = '/(?![^<]+>)(?<!\w)(' . preg_quote($t['label']) . ')\b/s'; 
$text = preg_replace_callback($find, 'replaceCallback', $text); 

echo "Find: $find\n"; 
echo 'Quote: ' . preg_quote($t['label']) . "\n"; 
echo "Result: $text\n"; 

/* Returns: 

Find: /(?![^<]+>)(?<!\w)(Test)\b/s 
Quote: Test 
Result: <p><a class="tag" rel="tag-definition" title="Click to know more about Test" href="?tag=Test">Test</a></p> 
Warning: preg_replace_callback() [function.preg-replace-callback]: Unknown modifier '\' in /test.php on line 25 
Find: /(?![^<]+>)(?<!\w)(\<em\>Test\</em\>)\b/s 
Quote: \<em\>Test\</em\> 

Result: 

*/ 

function replaceCallback($match) { 
    if (is_array($match)) { 
     $htmlVersion = $match[1]; 
     $urlVersion = urlencode($htmlVersion); 
     return '<a class="tag" rel="tag-definition" title="Click to know more about ' . $htmlVersion . '" href="?tag=' . $urlVersion . '">' . $htmlVersion . '</a>'; 
    } 
    return $match; 
} 
+0

ok, je pense que je l'ai eu, html n'est pas assez régulier pour les expressions régulières :) Mais alors, comment iriez-vous sur le remplacement des mots par des liens hypertexte dans un contenu html? – pixeline

+0

@pixeline: :-) Je suis désolée de vous le dire - c'est juste une question qui revient souvent dans tous les sens. Regexes peut sembler une bonne idée au début, mais rarement travailler. Quoi qu'il en soit, vous devriez probablement essayer les [fonctions DOM] (http://www.php.net/manual/fr/book.dom.php) en PHP. Le tutoriel [PHPro Parse HTML avec PHP et DOM] (http://www.phpro.org/examples/Parse-HTML-With-PHP-And-DOM.html) peut aussi aider. – Mike

+1

@pixeline Des questions comme la vôtre apparaissent au moins trois fois par jour. Recherchez * remplacer les attributs dans HTML * ou des mots-clés similaires ou simplement parcourir les questions quelques pages en arrière. La clé que vous voulez est DOM. – Gordon

Questions connexes