从HTML标记中删除on * JS事件属性

use*_*098 2 html javascript php regex events

请帮助您解析PHP简单的html字符串(php regexp)。我需要从html代码中删除html-js事件。我知道php正则表达式非常糟糕。

代码示例:

<button onclick="..javascript instruction..">

结果: <button>

<button onclick="..javascript instruction.." value="..">

结果: <button value="..">

<button onclick=..javascript instruction..>

结果: <button>

<button onclick=..javascript instruction.. value>

结果: <button value>

我需要在不使用引号的情况下执行此操作,因为所有现代浏览器都允许执行属性而无需使用仲裁。

注意:我nedd不仅解析onclick ..都是从'on'开始的所有属性。

注意事项(2):不要尝试建议HTML解析器,因为它对于解析而言将是非常大的树。

更新:谢谢您的回复!现在,我使用由我编写的HTMLPurifier组件一个小框架。

Qta*_*tax 5

用正则表达式标记没有错。但是,使用正则表达式制作完整的HTML标记器需要大量工作,而且很难正确完成。我建议使用适当的解析器,因为无论如何您可能都需要删除脚本标记。

假设不需要完整的令牌生成器,则以下正则表达式和代码可用于on*从HTML标记中删除属性。由于未使用适当的标记器,因此即使在脚本,注释,CDATA等中,它也会匹配看起来像标签的字符串。

无法保证将所有输入/浏览器组合的所有事件属性都删除!请参阅下面的注释。


容错注意事项

浏览器通常会容忍错误。因此,很难标记标记并获得属性,因为当存在“无效”数据时浏览器会看到它们。由于浏览器之间的容错能力和处理方式不同,因此不可能制定出一种适用于所有情况的解决方案。

因此:某些浏览器(当前版本,过去版本或将来版本)可以将我的代码认为不是标签的内容视为标签,然后执行JS代码。

在我的代码中,我尝试模仿最近的Google Chrome版本的标记的标记化(和容错/处理)。Firefox似乎采用类似的方式。

IE 7有所不同,在某些情况下,它的容忍度不那么高(这比容忍度更好)。(IE 6-不要去那里。请参阅XSS过滤器逃避备忘单


相关链接:


代码

$redefs = '(?(DEFINE)
    (?<tagname> [a-z][^\s>/]*+    )
    (?<attname> [^\s>/][^\s=>/]*+    )  # first char can be pretty much anything, including =
    (?<attval>  (?>
                    "[^"]*+" |
                    \'[^\']*+\' |
                    [^\s>]*+            # unquoted values can contain quotes, = and /
                )
    ) 
    (?<attrib>  (?&attname)
                (?: \s*+
                    = \s*+
                    (?&attval)
                )?+
    )
    (?<crap>    [^\s>]    )             # most crap inside tag is ignored, will eat the last / in self closing tags
    (?<tag>     <(?&tagname)
                (?: \s*+                # spaces between attributes not required: <b/foo=">"style=color:red>bold red text</b>
                    (?>
                        (?&attrib) |    # order matters
                        (?&crap)        # if not an attribute, eat the crap
                    )
                )*+
                \s*+ /?+
                \s*+ >
    )
)';


// removes onanything attributes from all matched HTML tags
function remove_event_attributes($html){
    global $redefs;
    $re = '(?&tag)' . $redefs;
    return preg_replace("~$re~xie", 'remove_event_attributes_from_tag("$0")', $html);
}

// removes onanything attributes from a single opening tag
function remove_event_attributes_from_tag($tag){
    global $redefs;
    $re = '( ^ <(?&tagname) ) | \G \s*+ (?> ((?&attrib)) | ((?&crap)) )' . $redefs;
    return preg_replace("~$re~xie", '"$1$3"? "$0": (preg_match("/^on/i", "$2")? " ": "$0")', $tag);
}
Run Code Online (Sandbox Code Playgroud)


用法示例

在线示例

$str = '
<button onclick="..javascript instruction..">
<button onclick="..javascript instruction.." value="..">
<button onclick=..javascript_instruction..>
<button onclick=..javascript_instruction.. value>
<hello word "" ontest = "hai"x="y"onfoo=bar/baz  />
';

echo $str . "\n----------------------\n";

echo remove_event_attributes($str);
Run Code Online (Sandbox Code Playgroud)

输出:

<button onclick="..javascript instruction..">
<button onclick="..javascript instruction.." value="..">
<button onclick=..javascript_instruction..>
<button onclick=..javascript_instruction.. value>
<hello word "" ontest = "hai"x="y"onfoo=bar/baz  />

----------------------

<button >
<button  value="..">
<button >
<button  value>
<hello word "" x="y"   />
Run Code Online (Sandbox Code Playgroud)