2009-07-05 131 views
7

我有一个字符串,HTML属性:PHP - 拆分HTML的字符串属性为索引数组

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

如何该字符串转换成一个索引数组,如:

array(
    'id' => 'header', 
    'class' => array('foo', 'bar'), 
    'style' => array(
    'background-color' => '#fff', 
    'color' => 'red' 
) 
) 

,所以我可以使用PHP array_merge_recursive函数来合并2组HTML属性。

谢谢

回答

8

您可以使用正则表达式来提取这些信息:

$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); 

现在你只需要解析的class类(以空格分割)和style属性声明(一有点难度,因为它可以包含注释和网址,其中包含;)。

+0

谢谢浓汤,您正则表达式很酷。 唯一的问题是$ attrs ['class']或$ attrs ['style']正在返回字符串:所以很难将它们与另一个$ attribs字符串合并,例如合并那两组属性: $ attribs1 ='class =“foo bar”'; $ attribs2 ='class =“lorem”'; 你有什么想法可以增强它? – abernier 2009-07-05 10:36:34

+0

我真的很喜欢这个解决方案...但我没有得到正则表达式xD它对我的头来说有一点点 – lumio 2012-07-10 20:46:37

+1

我刚刚写了一个替代正则表达式,它也解析了HTML5样式布尔属性(没有=符号)和使用引用的引用:`(\ w +)\ s *(= \ s *(['''))(。*?)\ 2 \ s)' – 2012-11-11 22:45:14

2

可能这可以帮助你.. 它做什么..

  • 一个HTML DOM解析器写在PHP5 +让你在一个非常简单的方法操作HTML!
  • 需要PHP 5+。
  • 支持无效的HTML。
  • 像jQuery一样用选择器在HTML页面上查找标签。
  • 从一行中提取HTML中的内容。

http://simplehtmldom.sourceforge.net/

3

不能使用正则表达式解析HTML的属性。这是因为语法是上下文的。您可以使用正则表达式来标记输入,但需要状态机来解析它。

如果性能是不是什么大不了的事,做最安全的方式,可能是在包装标签的属性,然后通过HTML解析器发送。例如:

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; 
} 

你也许可以优化上面,通过重用解析器,或使用XmlReadersax parser

17

使用的SimpleXML:

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

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

print_r($x); 

?> 

这假定属性始终名称/值对...

1

简单的方法可能是也:

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