2010-08-27 5 views
1

Je suis novice dans l'appariement de motifs, je l'ai finalement compris. Je suis coincé en essayant de trouver une approche au problème suivant.Motif correspondant aux balises html

Je dois renvoyer une correspondance (avec phg preg_match) si l'une des balises html est présente.

<p></p> 
<br> 
<h1></h1> 
<h2></h2> 

Et ne retourner aucune correspondance dans le cas contraire. Donc, quoi que ce soit pas dans la liste ci-dessus échoue, par exemple:

<script></script> 
<table></table> 

ect

... Et idéalement, je veux utiliser une liste blanche des étiquettes de sécurité si possible.

Quelqu'un connaît un modèle que je peux utiliser/adapter?

Répondre

2
preg_match_all('/<([a-z]*)\b[^>]*>(.*?)</\1>/i'$html,$matches); 

Briser l'expression

Le premier / est le séparateur

le < est le début de la balise, la première <

les ([a-z]*) commence à correspondre un nom de tag donc instance de sapin < forte

le \b[^>]* dit une fois que vous avez trouvé un espace, continuer à chercher tous les mots

le > dit qu'il veut la section précédente pour continuer à chercher jusqu'à ce qu'il trouve la première >

le (.*?) dit continuer à chercher et COLLECT (..) la chaîne à l'intérieur mais parce que nous avons un ? alors arrêtez de regarder lorsque vous trouvez le prochain char après l'accolade de fermeture.

le </\1> dit que je veux correspondre, mais seulement si la valeur se trouve dans le même que le premier match, cela se fait par \1 comme en match , the value of this would be what's found with ([a-z] *) `.

vous pouvez utiliser preg_match_all pour trouver tous avec le contenu, la sortie du réseau serait quelque chose comme

array(
    0 > THE WHOLE TAG 
    1 > TAG NAME 
    2 > TAG VALUE 
) 

it helps :)

exmaple

$allowed = array('b','strong','i','pre','code'); WHITELIST, never blacklist 
foreach($matchas as $match) 
{ 
    if(!in_array($match[1],$allowed)) 
    { 
     echo sprintf('The tag %s is disallowed!',$match[1]); 
    } 
} 
+0

Donc, cela retournerait toutes les balises en $ html, que je pourrais alors vérifier les balises non désirées? – YsoL8

+0

oui une mauvaise mise à jour avec l'exemple. – RobertPitt

+0

Merci! Semble simple. – YsoL8

5

Même si ce n'est pas la situation habituelle "I want to parse HTML with regular expressions", je recommanderais néanmoins d'utiliser un analyseur DOM, de parcourir chaque élément et d'abandonner s'il ne figure pas dans la liste des éléments autorisés.

Voir par exemple. this question pour commencer.

Il pourrait devenir presque une seule ligne en utilisant une extension de l'analyseur DOM comme phpQuery si elle prend en charge le sélecteur :not et les noms de balises multiples - Je ne sais pas, ont jamais travaillé avec moi-même, mais il sera facile de trouver en dehors. Les exemples de base sont here.

2

Regex est tout à fait inadapté à la vérification HTML pour les balises 'safe'. Non seulement cela, mais il n'y a pas de balises sécurisées en HTML. N'importe quel élément peut avoir des attributs qui permettent l'injection de script (par exemple onclick, style -with-IE-expression() ...). Vous devez vérifier chaque attribut ainsi que chaque élément. Lorsque votre sécurité est en jeu, vous avez absolument besoin d'un vrai analyseur HTML pour cela (ensuite vous filtrez les éléments/attributs et sérialisez les résultats). Il y a tellement de façons d'échapper aux contrôles basés sur regex que ce n'est même pas drôle.

Vous pouvez utiliser DOMDocument::loadHTML suivi d'une marche DOM pour ce faire, ou vous pouvez utiliser une bibliothèque existante telle que htmlpurifier.

Questions connexes