PHP - split a string of HTML attributes into an indexed array

后端 未结 6 828
后悔当初
后悔当初 2020-12-11 16:20

I\'ve got a string with HTML attributes:

$attribs = \' id= \"header \" class = \"foo   bar\" style =\"background-color:#fff; color: red; \"\';
相关标签:
6条回答
  • 2020-12-11 16:43

    A simple and effective function to solve this

    function attrString2Array($attr) {
      $atList = [];
    
      if (preg_match_all('/\s*(?:([a-z0-9-]+)\s*=\s*"([^"]*)")|(?:\s+([a-z0-9-]+)(?=\s*|>|\s+[a..z0-9]+))/i', $attr, $m)) {
        for ($i = 0; $i < count($m[0]); $i++) {
          if ($m[3][$i])
            $atList[$m[3][$i]] = null;
          else
            $atList[$m[1][$i]] = $m[2][$i];
        }
      }
    
      return $atList;
    }
    
    print_r(attrString2Array('<li data-tpl-classname="class" data-tpl-title="innerHTML" disabled nowrap href="#" hide src = "images/asas.gif">'));
    print_r(attrString2Array('data-tpl-classname="class" data-tpl-title="innerHTML" disabled nowrap href="#" hide src = "images/asas.gif"'));
    
    //Array
    //(
    //    [data-tpl-classname] => class
    //    [data-tpl-title] => innerHTML
    //    [disabled] => 
    //    [nowrap] => 
    //    [href] => #
    //    [hide] => 
    //    [src] => images/asas.gif
    //)

    0 讨论(0)
  • 2020-12-11 16:49

    You can't use a regular expression to parse html-attributes. This is because the syntax is contextual. You can use regular expressions to tokenize the input, but you need a state machine to parse it.

    If the performance isn't a big deal, the safest way to do it, is probably to wrap the attributes in a tag and then send it through an html parser. 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;
    }
    

    You could probably optimize the above, by reusing the parser, or by using XmlReader or the sax parser.

    0 讨论(0)
  • 2020-12-11 16:54

    Use SimpleXML:

    <?php
    $attribs = ' id= "header " class = "foo   bar" style ="background-color:#fff; color: red; "';
    
    $x = new SimpleXMLElement("<element $attribs />");
    
    print_r($x);
    
    ?>
    

    This assumes that the attributes are always name/value pairs...

    0 讨论(0)
  • 2020-12-11 16:54

    Easy way could be also:

    $atts_array = current((array) new SimpleXMLElement("<element $attribs />"));
    
    0 讨论(0)
  • 2020-12-11 16:57

    May be this helps you .. What it does ..

    • A HTML DOM parser written in PHP5+ let you manipulate HTML in a very easy way!
    • Require PHP 5+.
    • Supports invalid HTML.
    • Find tags on an HTML page with selectors just like jQuery.
    • Extract contents from HTML in a single line.

    http://simplehtmldom.sourceforge.net/

    0 讨论(0)
  • 2020-12-11 16:59

    You could use a regular expression to extract that 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);
    

    Now you just need to parse the classes of class (split at whitespaces) and property declarations of style (a little bit harder as it can contain comments and URLs with ; in it).

    0 讨论(0)
提交回复
热议问题