如何匹配内联样式中的字符?

时间:2017-12-10 02:55:10

标签: php html css regex

我希望在内联样式中匹配一个字母或数字或符号。

示例:

<html>
    <head>
    </head>
    <body>
        <p style="color: #48ad64;font-weight:10px;">hi there</p>
        <div style="background-color: #48ad64;">
            <h3>perfect</h3>
        </div>
    </body>
</html>

我想匹配任何co#4;-

如果我们以o为例,它应该匹配5次。

我想使用preg_replace()替换样式声明中的每个匹配项。

我怎么能得到这个?我尝试了很多不同的表达方式,但没有一个能达到我想要的效果。

我尝试过的一些内容:

  1. /(?:\G(?!^)|\bstyle=")(?:.{0,}?)(o)(?=[^>]*>)/

  2. /(style=")(?:\w+)(o)(([^"]*)")/

  3. 我只需要正则表达式匹配HTML中的所有o。我期待这个:

    <html> 
       <head> 
       </head> 
       <body>
          <p style="c'o'lor: #48ad64;f'o'nt-weight:10px;">how blabla</p> 
          <div style="backgr'o'und-c'o'l'o'r: #48ad64;">
              <h3>perfect normal o moral bla bal</h3> 
          </div> 
       </body> 
    </html>
    

    我只想让上面内联式内部的所有o次出现都替换为'o'

1 个答案:

答案 0 :(得分:2)

快速/肮脏/简单的解决方案是将preg_replace_callback()str_replace()一起使用。

模式:(Demo with Pattern Explanation/<[^<]+ style="\K.*?(?=">)/

代码:(Demo

$html='<html>
    <head>
    </head>
    <body>
        <p style="color: #48ad64;font-weight:10px;">hi there</p>
        <div style="background-color: #48ad64;">
            <h3>perfect</h3>
        </div>
    </body>
</html>';

$needle="o";
echo preg_replace_callback('/<[^<]+ style="\K.*?(?=">)/',function($m)use($needle){return str_replace($needle,"<b>$needle</b>",$m[0]);},$html);
//   add the i flag for case-insensitive matching------^                                     ^-- and add i here for case-insensitive replacing

输出:

<html>
    <head>
    </head>
    <body>
        <p style="c<b>o</b>l<b>o</b>r: #48ad64;f<b>o</b>nt-weight:10px;">hi there</p>
        <div style="backgr<b>o</b>und-c<b>o</b>l<b>o</b>r: #48ad64;">
            <h3>perfect</h3>
        </div>
    </body>
</html>

这是纯正的正则表达式替换方法/模式:

$needle="o";
//                                               vv-----------vv--make the needle value literal
echo preg_replace('/(?:\G(?!^)|\bstyle=")[^"]*?\K\Q'.$needle.'\E/',"'$needle'",$html);
//        assumes no escaped " in style--^^^^  ^^-restart fullstring match

[^"]*?组件消除了对前瞻的需求。但是,如果字体系列名称(或类似名称)使用\"(转义双引号),则替换准确性会受到负面影响。

我不会调用这些方法中的任何一种&#34; robust&#34;因为文本的某些子串可能会欺骗模式过度匹配&#34;非法风格子串。

为了做到这一点,我建议你使用DomDocument或其他一些html解析器来确保你只修改真实/真实的样式属性。

DomDocument代码:(Demo

$dom = new DOMDocument;
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // 2nd params to remove DOCTYPE 
$xp = new DOMXpath($dom);
foreach ($xp->query('//*[@style]') as $node) {
    $node->setAttribute('style',str_replace($needle,"'$needle'",$node->getAttribute('style'))); // no regex
}
echo $dom->saveHTML();