2016-04-21 91 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>/ 

的部分:

[^<]*? 

匹配沒有任何字符'< 」。這確保'腳本'標籤和谷歌字符串之間沒有任何其他標籤。