我有一个看起来像这样的变量:
$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似乎是一种邪恶的做法,或者在这种情况下它是否正常?
答案 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与正则表达式快速匹配 疯狂,就像克苏鲁喜欢它一样。
- 我认为在这种特定情况下选择正则表达式时我认为是好的,理性的,(半)可辩护的理由。