2010-06-19 9 views
2

J'ai beaucoup étudié ce sujet, mais je n'ai pas trouvé d'exemple de travail pour faire correspondre les balises html imbriquées avec les attributs. Je sais qu'il est possible de faire correspondre des balises internes équilibrées/imbriquées sans attributs (par exemple, une expression rationnelle pour et serait #<div\b[^>]*>(?:(?> [^<]+) |<(?!div\b[^>]*>))*?</div> # x).Expression régulière pour les balises imbriquées (la plus simple pour faciliter les choses)

Cependant, je voudrais voir un motif regex qui trouve une paire de balises HTML avec des attributs.

Exemple: Il devrait essentiellement correspondre

<div class="aaa"> **<div class="aaa">** <div> <div> </div> **</div>** </div> 

et non

<div class="aaa"> **<div class="aaa">** <div> <div> **</div>** </div> </div> 

Tout le monde a des idées?

Pour des fins de test, nous pourrions utiliser: http://www.lumadis.be/regex/test_regex.php


PS. Steven a mentionné une solution dans son blog (en fait dans un commentaire), mais il ne fonctionne pas

http://blog.stevenlevithan.com/archives/match-innermost-html-element

$regex = '/<div\b[^>]+?\bid\s*=\s*"MyID"[^>]*>(?:((?:[^<]++|<(?!\/?div\b[^>]*>))+)|(<div\b[^>]*>(?>(?1)|(?2))*<\/div>))?<\/div>/i'; 
+1

Il est généralement pas une bonne idée d'essayer d'analyser html/xml avec regex. Si vous pouviez nous dire précisément ce que vous essayez de faire, nous serons peut-être en mesure de vous orienter dans une direction plus appropriée: o) – vimist

+0

Juste pour clarifier. Ceci est plus d'une discussion théorique, juste pour le plaisir. Bien sûr, dans la vraie vie, j'utiliserais xpath ou plus. Je comprends que regex "state fini" ou "true" ne sont pas capables de le faire, mais qu'en est-il de la regex PHP/PCRE (qui ne sont plus regex "classique", par exemple ils supportent même des patterns récursifs? . - Dave il y a 0 secondes edit – Dave

Répondre

1

RegEx match open tags except XHTML self-contained tags

Et en effet, il est absolument impossible. HTML a quelque chose d'unique, quelque chose de magique, qui est immunisé contre RegEx.

+1

* quelque chose de magique, qui est immunisé contre RegEx * == XML, HTML, et les amis ne sont pas des langues régulières –

+1

Il est déjà assez difficile de voir * links * à The Rant dans toutes les autres questions; la copier va trop loin. Ce n'est pas drôle, et surtout, ce n'est pas utile. –

+0

Juste pour clarifier. Ceci est plus d'une discussion théorique, juste pour le plaisir. Bien sûr, dans la vraie vie, j'utiliserais xpath ou plus. Je comprends que "regex à états finis" ou "true" ne sont pas capables de le faire, mais qu'en est-il de la syntaxe PHP/PCRE de regex (qui ne sont plus vraiment regex "classiques", par exemple ils supportent même des patterns récursifs? R). – Dave

2

J'ai construit un script python bref pour résoudre le problème de la gestion de balises imbriquées. Il fonctionne heureusement avec html et avec d'autres syntaxes imbriquées terribles, comme le code wiki. Hyroniquement, je l'ai écrit pour éviter regex! Je ne pouvais pas les comprendre du tout. :-(. J'ai utilisé cette fonction pour quoi que ce soit, il est rapide Ce trop court très bien pour HTML et XML., Car il utilise uniquement la recherche de chaîne de base. Je suis très heureux de savoir que regex ne peut pas aider. :-)

Je voudrais partager le script, si quelqu'un d'entre vous est intéressé; mais considérez, je ne suis pas un programmeur, je présume que la question a été résolue depuis longtemps!

Vous pouvez me trouver à ma page de discussion en it.source: http://it.wikisource.org/wiki/Discussioni_utente:Alex_brollo

1

paires correspondant plus à l'intérieur de <div> & </div> balises, ainsi que leurs attributs & contenu:

#<div(?:(?!(<div|</div>)).)*</div>#s

La clé ici est que (?:(?!STRING).)* est en caractères que [^CHAR]* est en caractères.

Crédit: https://stackoverflow.com/a/6996274


Exemple en PHP:

<?php 

$text = <<<'EOD' 
<div id="1"> 
    in 1 
    <div id="2"> 
    in 2 
    <div id="3"> 
     in 3 
    </div> 
    </div> 
</div> 
<div id="4"> 
    in 4 
    <div id="5"> 
    in 5 
    </div> 
</div> 
EOD; 

$matches = array(); 
preg_match_all('#<div(?:(?!(<div|</div>)).)*</div>#s', $text, $matches); 

foreach ($matches[0] as $index => $match) { 
    echo "************" . "\n" . $match . "\n"; 
} 

Sorties:

************ 
<div id="3"> 
     in 3 
    </div> 
************ 
<div id="5"> 
    in 5 
    </div>