我在寻找解析HTML标记属性时发现了这个有用的正则表达式代码:
(\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?
效果很好,但缺少一个我需要的关键元素。一些属性是事件触发器,其中包含内联Javascript代码,如下所示:
onclick="doSomething(this, 'foo', 'bar');return false;"
或者:
onclick='doSomething(this, "foo", "bar");return false;'
我无法弄清楚当原始表达式嵌入包含属性值的引号集内时,如何使原始表达式不计算来自JS(单引号或双引号)的引号。
我应该补充说,这不是用于解析整个HTML文档。它在我更新的旧“数组选择菜单”功能中用作参数。其中一个参数是一个标签,可以将额外的HTML属性附加到表单元素。
我已经改进了函数并且不赞成旧的...但是如果代码中的某个地方是对旧函数的调用,我需要它将它们解析成新的数组格式。例如:
// Old Function
function create_form_element($array, $type, $selected="", $append_att="") { ... }
// Old Call
create_form_element($array, SELECT, $selected_value, "onchange=\"something(this, '444');\"");
新版本采用attr =>数组值对创建额外的标签。
create_select($array, $selected_value, array('style' => 'width:250px;', 'onchange' => "doSomething('foo', 'bar')"));
这只是一个向后兼容性问题,所有对OLD函数的调用都被路由到新函数,但是旧函数中的$ append_att参数需要被创建为新函数的数组,因此我需要使用正则表达式解析小HTML片段。如果有更好,更轻量级的方法来实现这一目标,我愿意接受建议。
答案 0 :(得分:2)
正则表达式的问题在于它尝试同时处理单引号和双引号。它不支持包含其他引用的属性值。这个正则表达式会更好用:
(\w+)=("[^<>"]*"|'[^<>']*'|\w+)
答案 1 :(得分:1)
以下正则表达式将按照此处提供的HTML语法规范工作
http://www.w3.org/TR/html-markup/syntax.html
正则表达式
// valid tag names
$tagname = '[0-9a-zA-Z]+';
// valid attribute names
$attr = "[^\s\\x00\"'>/=\pC]+";
// valid unquoted attribute values
$uqval = "[^\s\"'=><`]*";
// valid single-quoted attribute values
$sqval = "[^'\\x00\pC]*";
// valid double-quoted attribute values
$dqval = "[^\"\\x00\pC]*";
// valid attribute-value pairs
$attrval = "(?:\s+$attr\s*=\s*\"$dqval\")|(?:\s+$attr\s*=\s*'$sqval')|(?:\s+$attr\s*=\s*$uqval)|(?:\s+$attr)";
,最终的正则表达式查询将是
// start tags + all attr formats
$patt[] = "<(?'starttags'$tagname)(?'tagattrs'($attrval)*)\s*(?'voidtags'[/]?)>";
// end tags
$patt[] = "</(?'endtags'$tagname)\s*>"; // end tag
// full regex pcre pattern
$patt = implode("|", $patt);
// search and match
preg_match_all("#$patt#imuUs",$data,$matches);
希望这会有所帮助。
答案 2 :(得分:0)
更好的方法是使用反向引用,在PHP中,正则表达式为:
([a-zA-Z_:][-a-zA-Z0-9_:.]+)=(["'])(.*?)\\2
\\2
是对(["'])
此正则表达式也会匹配包含_
,-
和:
的属性,这些属性是根据W3C允许的,但是,此表达式不会匹配引号中未包含的值的属性