从PHP中的字符串中提取html属性

时间:2014-04-24 07:51:52

标签: php arrays function parsing dom

我有一个看起来像这样的变量:

$var = '<li data-tpl-classname="class" data-tpl-title="innerHTML"></li>'

我希望以某种方式提取data-tpl属性,所以我得到一个如下所示的结果数组:

$array = (
    'classname' => 'class',
    'title' => 'innerHTML'
)

“data-tpl-”属性的数量各不相同,并且它并不总是<li>元素。除此之外,它始终遵循相同的格式:data-tpl-attributename="attributePlacement"

如何检索这些属性并将其存储在数组中,不使用正则表达式?我说没有正则表达式,因为我看起来像使用正则表达式解析html似乎是一种邪恶的做法,或者在这种情况下它是否正常?

3 个答案:

答案 0 :(得分:2)

您可以很好地使用DOMDocument类,并且不使用正则表达式。这只是一个开始,你可以很好地探索它。

<?php
$var = '<li data-tpl-classname="class" data-tpl-title="innerHTML"></li>';
echo "<pre>";

function parseTag($content,$tg)
{
    $dom = new DOMDocument;
    $dom->loadHTML($content);
    $attr = array();
    foreach ($dom->getElementsByTagName($tg) as $tag) {
        foreach ($tag->attributes as $attribName => $attribNodeVal)
        {
           $attr[$attribName]=$tag->getAttribute($attribName);
        }
    }
    return $attr;
}

$attrib_arr = parseTag($var,'li');
print_r($attrib_arr);

<强> OUTPUT :

Array
(
    [data-tpl-classname] => class
    [data-tpl-title] => innerHTML
)

<强> Demo

答案 1 :(得分:2)

您可以使用一些字符串函数来提取值。它看起来像这样:

$test1 = '<li data-tpl-classname="class" data-tpl-title="innerHTML"></li>';
$test2 = '<div data-tpl-anything="something" data-tpl-title="this is a title" data-tpl-third="asdasd"></div>';

var_dump(extract_tpl($test1));
var_dump(extract_tpl($test2));

function extract_tpl($string,$prefix="data-tpl-") {
    $start = 0;
    $end = 0;

    while(strpos($string,$prefix,$end))
    {
        $start = strpos($string,$prefix,$start)+strlen($prefix);
        $end = strpos($string,'"',$start)-1;
        $end2 = strpos($string,'"',$end+2);
        $array[substr($string,$start,$end-$start)] = substr($string,$end+2,$end2-$end-2);
    }

    return $array;
}

输出:

array (size=2)
  'classname' => string 'class' (length=5)
  'title' => string 'innerHTML' (length=9)

array (size=3)
  'anything' => string 'something' (length=9)
  'title' => string 'this is a title' (length=15)
  'third' => string 'asdasd' (length=6)

代码中的数字(-1,+ 2,...)用于跳过像“。

这样的符号

答案 2 :(得分:0)

没有它完全是邪恶的,当然,它可能在大字符串或真正复杂的正则表达式上很慢,这不是你的情况。它仍然(更具可读性?),比HTML或XML解析器更容易,更快速地实现,它们不比简单的正则表达式匹配更优化。

$var = '<li data-tpl-classname="class" data-tpl-title="innerHTML"></li>'
preg_match_all("data-tpl-([^"]*)="([^"]*)"/i", $str, $matches);

$array = array();
for($i = 1, $size = count($matches); $i < $size; ++$i){
  $array[$matches[$i][0]] = $matches[$i][1];
}

我使用[^"]*代替.*?,因为它更快一些。


注意:我刚做了一个基准。与使用DOMDocument的第一个答案相比,使用Regexp的代码速度提高了4倍,但由于使用regexp解析Dom可能会导致对标记的错误解释,因此不太清晰。它比使用str函数的答案稍慢(但更容易阅读和维护)。

注2:当然只有在不会出现任何混淆的情况下使用此解决方案,并且如果您确定输入格式,相反,DOMDocument的解决方案更清晰。


为什么在解析HTML时应明智地使用正则表达式:

http://blog.codinghorror.com/parsing-html-the-cthulhu-way

请记住这些:

  
      
  • 这通常是一个坏主意。
  •   
  • 除非你有纪律并且对你正在做的事情施加非常严格的条件,否则将HTML与正则表达式快速匹配   疯狂,就像克苏鲁喜欢它一样。
  •   
  • 我认为在这种特定情况下选择正则表达式时我认为是好的,理性的,(半)可辩护的理由。
  •