正则表达式在html中找到Src属性但不在脚本标记内找到

时间:2016-07-10 20:20:39

标签: php regex

我想用PHP替换我的html中的所有src路径。

$str = preg_replace_callback('@src=\s*(?:["|\'])?([^ >"\']+)@i',array($this, 'html_src'), $str);

此代码在html中找到所有src,如

我用绝对网址替换这些网址。

但我不希望这个正则表达式在标签内找到src,因为这是个问题。

<script>function e(a){var c=b.createElement("script");c.src=a,c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}</script>

就像我们在脚本标签中找到src并用url替换它然后js给出错误。

请你帮我扩展正则表达式。

1 个答案:

答案 0 :(得分:1)

改为使用解析器:

<?php

$data = <<<DATA
This is an image source: <img src='/images/football.png'>
This one is inside script tags:
<script>function e(a){var c=b.createElement("script");c.src=a,c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}</script>
DATA;

$dom = new DOMDocument();
$dom->loadHTML($data);

$xpath = new DOMXPath($dom);
$images = $xpath->query("//img");
foreach ($images as $image) {
    $image->setAttribute('src', 'some_new_url_here');
}
echo $dom->saveHTML();
?>

请参阅a demo on ideone.com

<小时/> 要显示正则表达式替代方法,您可以使用(*SKIP)(*FAIL)提供的PCRE机制。我们的想法是匹配您不想要的所有内容(即<script>标签),然后将其从整体匹配中排除:

not_this|forget_this(*SKIP)(*FAIL|but_keep_this

对于您的示例,这归结为:

<script>[\s\S]*?</script>(*SKIP)(*FAIL)
|
\bsrc=(['"]).+?\1

请参阅a demo for this one on regex101.com

<小时/> 这有几个瑕疵经常在SO上讨论,最喜欢的答案是being this one