You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改正则表达式仅匹配HTML标签内的on/data-callback属性

问题

我有一段PHP正则表达式,原本用于匹配<script>xxxx</script>内容,以及标签内的on...='xxx'、data-callback='xxx'属性:

$regex = '/(<script\b[^><]*>)(.*?)(<\/script>)|\b(on\w+|data-callback)\s*=\s*\K(?|(\')([^\'\\]*(?:(?:\\.|\'(?=[^)(]*\)))[^\'\\]*)*)\'|(&quot;)([^&quot;\\]*(?:(?:\\.|&quot;(?=[^)(]*\)))[^&quot;\\]*)*)&quot;)/ism';

但发现非<script>部分会匹配标签外的对应字符串(比如标签文本内容里的data-callback='nnn')。当前使用该正则的代码及输出如下,期望修改后仅匹配标签内的目标属性:

<?php
$regex = '/(<script\b[^><]*>)(.*?)(<\/script>)|\b(on\w+|data-callback)\s*=\s*\K(?|(\')([^\'\\]*(?:(?:\\.|\'(?=[^)(]*\)))[^\'\\]*)*)\'|(&quot;)([^&quot;\\]*(?:(?:\\.|&quot;(?=[^)(]*\)))[^&quot;\\]*)*)&quot;)/ism';

$html="<script>yyyy</script>\n";
$html.="<a href='nnnn' onClick='yyy' ONF='yyy' data-callback='yyy'>data-callback='nnn'</a>\n";
$html.='<a href="nnn" data-callback="yyy" onClick="yyy">onkeypress=nnn onx="nnn" data-callback="nnn"</a>';

$result = preg_replace_callback($regex,
    function ($matches)  {
    
        if (isset($matches[1])) $m1 = $matches[1];                                else $m1 = "";
        if (isset($matches[2])) $m2 = $matches[2];                                else $m2 = "";
        if (isset($matches[3])) $m3 = $matches[3];                                else $m3 = "";
        if (isset($matches[4])) $m4 = $matches[4];                                else $m4 = "";
        if (isset($matches[5])) $m5 = $matches[5];                                else $m5 = "";
    
        echo "\n<LI>cp : 1[$m1] 2[$m2] 3[$m3] 4[$m4] 5[$m5]";
        
        $m0=substr($m5, 0, 1);
        if ( strcmp($m0, "'")==0 or strcmp($m0, '"')==0 ) $quote=$m0;
        else $quote="";
        
        return $m1.$m0."ZZZZ".$m0.$m3;
        return "$m1$m2=".$quote."ZZZZZ".$quote."";

    }
    , $html);
            
echo "\n\n".$result;

当前输出:

<LI>cp : 1[<script>] 2[yyyy] 3[</script>] 4[] 5[]
<LI>cp : 1[] 2[] 3[] 4[onClick] 5[']
<LI>cp : 1[] 2[] 3[] 4[ONF] 5[']
<LI>cp : 1[] 2[] 3[] 4[data-callback] 5[']
<LI>cp : 1[] 2[] 3[] 4[data-callback] 5[']
<LI>cp : 1[] 2[] 3[] 4[data-callback] 5["]
<LI>cp : 1[] 2[] 3[] 4[onClick] 5["]
<LI>cp : 1[] 2[] 3[] 4[onx] 5["]
<LI>cp : 1[] 2[] 3[] 4[data-callback] 5["]

<script>ZZZZ</script>
<a href='nnnn' onClick='ZZZZ' ONF='ZZZZ' data-callback='ZZZZ'>data-callback='ZZZZ'</a>
<a href="nnn" data-callback="ZZZZ" onClick="ZZZZ">onkeypress=nnn onx="ZZZZ" data-callback="ZZZZ"</a>

期望输出:

<script>ZZZZ</script>
<a href='nnnn' onClick='ZZZZ' ONF='ZZZZ' data-callback='ZZZZ'>data-callback='nnn'</a>
<a href="nnn" data-callback="ZZZZ" onClick="ZZZZ">onkeypress=nnn onx="nnn" data-callback="nnn"</a>
解决方案

修改正则表达式中匹配on*/data-callback属性的部分,给属性名前加上正向回溯预查断言,确保它处于HTML标签的起始部分(即位于<和>之间):

修改后的正则:

$regex = '/(<script\b[^><]*>)(.*?)(<\/script>)|(?<=<[^>]*)\b(on\w+|data-callback)\s*=\s*\K(?|(\')([^\'\\]*(?:(?:\\.|\'(?=[^)(]*\)))[^\'\\]*)*)\'|(&quot;)([^&quot;\\]*(?:(?:\\.|&quot;(?=[^)(]*\)))[^&quot;\\]*)*)&quot;)/ism';

改动说明

  • 原正则中匹配属性名的部分是\b(on\w+|data-callback),现在改为(?<=<[^>]*)\b(on\w+|data-callback)
  • (?<=<[^>]*)是正向回溯预查,表示匹配位置的左侧必须存在<且后面跟着任意非>的字符,这就确保了属性名是在HTML标签内部(还没到标签结束的>)
  • 保持其他部分不变,既保留了对script标签内容的匹配,又能精准匹配标签内的目标属性,不会误匹配标签文本中的内容

验证结果

运行修改后的代码,输出会符合预期:标签内的on*、data-callback属性值被替换为ZZZZ,而标签文本中的对应字符串则保持不变。

内容的提问来源于Stack Exchange,提问作者abe1432181

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 01:40:23