11
votes

Php - diviser une chaîne d'attributs HTML en une matrice indexée

J'ai une chaîne avec des attributs HTML: xxx

Comment transformer cette chaîne en une matrice indexée, comme: xxx

Donc, je peux utiliser la fonction php array_merge_recrsive pour fusionner 2 ensembles d'attributs HTML.

merci


0 commentaires

6 Réponses :


8
votes

Vous pouvez utiliser une expression régulière pour extraire cette information:

$attribs = ' id= "header " class = "foo   bar" style ="background-color:#fff; color: red; "';
$pattern = '/(\\w+)\s*=\\s*("[^"]*"|\'[^\']*\'|[^"\'\\s>]*)/';
preg_match_all($pattern, $attribs, $matches, PREG_SET_ORDER);
$attrs = array();
foreach ($matches as $match) {
    if (($match[2][0] == '"' || $match[2][0] == "'") && $match[2][0] == $match[2][strlen($match[2])-1]) {
        $match[2] = substr($match[2], 1, -1);
    }
    $name = strtolower($match[1]);
    $value = html_entity_decode($match[2]);
    switch ($name) {
    case 'class':
        $attrs[$name] = preg_split('/\s+/', trim($value));
        break;
    case 'style':
        // parse CSS property declarations
        break;
    default:
        $attrs[$name] = $value;
    }
}
var_dump($attrs);


2 commentaires

Merci Gumbo, votre regex est cool. Le seul problème est que $ attractions ['classe'] ou $ attractions [style '] renvoie des chaînes: il sera donc difficile de les fusionner avec une autre chaîne Attribs $, par exemple en fusionnant 2 ensembles d'attribs: $ attribs1 =' classe = "foo bar" '; $ attribs2 = 'classe = "lorem"'; Dans une "classe =" Foo Bar Lorem "" C'est pourquoi j'aimerais que les attractions $ ["classe"] renvoie un tableau: Array ("FOO", 'Bar') Avez-vous une idée d'améliorer cela?


Je viens d'écrire une alternative Regex qui analyse également des attributs booléens de style HTML5 (sans signe =) et utilise une référence arrière pour les citations: (\ w +) \ s * (= \ s * (["'] ) (. *?) \ 2 \ s)?



3
votes

Peut-être que cela vous aide .. Ce que ça fait ..

  • Un analyseur HTML DOM écrit dans PHP5 + vous permet de manipuler HTML de manière très facile!
  • nécessite PHP 5 +.
  • prend en charge HTML non valide.
  • Trouvez des balises sur une page HTML avec des sélecteurs, comme JQuery.
  • extraire le contenu de HTML dans une seule ligne.

    http://simplehtmldom.sourceforge.net/


1 commentaires

Notez que la seule raison pour laquelle je me suis retrouvé ici est que la DOMProcessinginstruction a un champ de données qui est le texte qui est le texte suivant le texte et ?> . En cas d'étiquette telle que: vous obtenez une plaine String comme: type = "text / xsl" href = "https://sms.m2osw.com/sitemap.xsl" que vous devez analyser en tant qu'attributs.



5
votes

Vous ne pouvez pas utiliser une expression régulière pour analyser les attributs HTML. En effet, la syntaxe est contextuelle. Vous pouvez utiliser des expressions régulières pour jeton de l'entrée, mais vous avez besoin d'une machine d'état pour l'analyser.

Si la performance n'est pas une grosse affaire, le moyen le plus sûr de le faire est probablement d'envelopper les attributs dans une balise et Puis envoyez-le à travers un analyseur HTML. EG. --

function parse_attributes($input) {
  $dom = new DomDocument();
  $dom->loadHtml("<foo " . $input. "/>");
  $attributes = array();
  foreach ($dom->documentElement->attributes as $name => $attr) {
    $attributes[$name] = $node->value;
  }
  return $attributes;
}


3 commentaires

Analysez ceci: FOO = 'BAR' CUUX = "O'RELEY" ZIP = "\" ZAP \ ""


@troelskn: La troisième déclaration de valeur d'attribut est invalide. Le " doit être représenté par des références de caractères.


Tu as raison - je n'étais pas au courant de ça. Je suggérerais toujours d'utiliser un analyseur XML / HTML, pour tenir compte de toutes sortes de cas de bord impairs.



22
votes

Utilisez simplexml:

<?php
$attribs = ' id= "header " class = "foo   bar" style ="background-color:#fff; color: red; "';

$x = new SimpleXMLElement("<element $attribs />");

print_r($x);

?>


0 commentaires

6
votes

Un moyen facile pourrait aussi:

$atts_array = current((array) new SimpleXMLElement("<element $attribs />"));


0 commentaires

2
votes

Une fonction simple et efficace pour résoudre ce xxx


2 commentaires

Bienvenue à Stackoverflow! Veuillez éditer votre réponse pour fournir une explication de votre code. Cela améliorera la qualité de votre réponse et le rendra plus probable que cela soit évité :)


Avez-vous remarqué que la question de l'OP est à la recherche d'un résultat multidimensionnel?