2016-04-21 89 views
1

我想检查一个网页的谷歌分析脚本标记的存在。这似乎应该很容易,但我的正则表达式技能似乎缺乏。所以作为一个简单的例子,我试图匹配它们之间具有“谷歌分析”的开放和关闭脚本标签。PHP的正则表达式匹配标记先行问题

因此,例如,如果您有:

<script scr="whatever"></script> 
<script>other script</script> 
blah blah blah 
<script> 
    blah blah google-analytics 
<script> 

然后在正则表达式:

/<script>([s/S/]*?google-analtics[s/S/]*?)<\/script>/ 

这将返回从第一个脚本标记一个字符串,并包括其他的脚本标记。因此,像:

other script</script> blah blah blah <script> blah blah google-analytics 

但是,当然,我只希望字符串

blah blah google-analytics 

所以接下来的一步,包括提前负的样子:

/<script>((?![s/S/]*?script)[s/S/]*?google-analytics[s/S/]*?)<\/script>/ 

但是,没有按” t似乎工作。我尝试了一组不同的捕捉组合和'[s/S /] *?'在前面和后面。

基本上我试图匹配一个字符串,只要它不包含子字符串。这听起来像是一个常见的问题,但对于我来说,我无法去工作。我有谷歌一吨,所有的例子都很简单,但似乎没有工作。我一直在使用https://regex101.com/r/hN5dK5/2

任何洞察将有所帮助。 (脚本以php身份运行)

回答

2

正则表达式的方法

首先,使用verbose模式有更好的可读性。
考虑下面的正则表达式,则:

<script>     # match "<script>" literally 
(?:(?!</script>)[\s\S])* # match anything except "</script>" 
(?:google-analytics)  # look for "google-analytics" literally 
(?:(?!</script>)[\s\S])* # same pattern as above 
</script>    # closing "</script>" tag 

your updated demo看到一个演示了这种方法。


分析器方法(S)

的SimpleXML

一般而言,分析HTML用正则表达式被认为是不好的做法,对SO(见this famous post),所以你还不如用的方法与解析器并适当xpath查询:

$xml = simplexml_load_string($html); 
$scripts = $xml->xpath("//script[contains(text(),'google-analytics')]"); 
print_r($scripts); 

查看demo on ideone.com

DOM文档

有人可能会说,这SimpleXML是不是真的需要解析HTML文件(而XML文件顾名思义),所以为了完整起见,最后用DOMDocument一个例子:

$doc = new DOMDocument(); 
$doc->loadHTML($html); 

$xpath = new DOMXpath($doc); 
$scripts = $xpath->query("//script[contains(text(),'google-analytics')]"); 
foreach ($scripts as $script) { 
    // do sth. useful here 
    print_r($script); 
} 
+0

确实在搜索DOM标签时,使用DOM解析器通常是更好的路径。尽管所有PHP Dom解析器都有副作用。例如,如果您想添加脚本标记(如果缺少脚本标记),那么我发现的所有DOM解析器都会更改其余的html。这只是一个问题,如果你希望你的html格式化为人类的可读性。 –

0

问题是,展望未来一直到页面末尾,因此它可能工作,但只能在最后一个脚本标记上。

我周围的工作发现是限制通配符搜索比“<”其他任何问题,例如:

/<script[^>]*>([^<]*?google-analytics.com[\s\S]*?)<\/script>/ 

的部分:

[^<]*? 

匹配没有任何字符'< ”。这确保'脚本'标签和谷歌字符串之间没有任何其他标签。