2009-01-14 146 views
2

我有一個CMS,它使用基於HTML註釋的語法來讓用戶插入用戶無法輕鬆插入的Flash視頻播放器,幻燈片和其他「硬」代碼寫。正則表達式來查找和替換HTML註釋標籤的內容

一個FLV電影的語法如下: <!--PLAYER=filename.flv-->

我用這個代碼:

$find_players = preg_match("/<!--PLAYER\=(.*)-->/si", $html_content, $match);

這個偉大的工程,如果只有一個球員,$匹配[1]包含文件名(這是我需要的)

我對正則表達式的認識正在消失,所以我無法調整這個來獲取多個匹配。

如果有更多的頁面,它打破完全,因爲它匹配太貪婪地(從第一<!--PLAYER到最後-->

+0

我想你想在「si」之後加一個「g」來做全局搜索嗎? – some 2009-01-14 00:11:11

回答

2

你可能需要一個正則表達式修飾符U(PCRE_UNGREEDY,不合適地匹配)。這會獲得儘可能短的匹配,這意味着你不會從開頭匹配o f頭< - PLAYER =到最後的結束 - >

縮寫的例子:

<?php 
$text = "blah\n<!-x=abc->blah<!-x=def->blah\n\nblah<!-x=ghi->\nblahblah" ; 
$reg = "/<!-x=(.*)->/U" ; 
preg_match_all($reg, $text, $matches) ; 
print_r($matches) ; 

您的代碼就變成了:

$find_players = preg_match_all("/<!--PLAYER=(.*)-->/Ui", $html_content, $matches); 
// print $matches[1] ; 

'S' 的修正(PCRE_DOTALL)可能也沒有幫助,你不可能有一個帶有換行符的文件名。

編輯:@Stevens建議這種語法,我同意是稍微更清楚 - 移動U修飾符捕獲括號。

$find_players = preg_match_all("/<!--PLAYER=(?U)(.*)-->/i", $html_content, $matches); 
1
$find_players = preg_match("/<!--PLAYER\=(.*?)-->/i", $html_content, $match); 

*?

應該工作很好,

+0

這裏不需要'm'(多行)標誌;它改變了未被使用的^和$元字符的含義。這是允許點匹配行分隔符的's'標誌。 – 2009-01-14 02:05:15

+0

這裏不需要s和m修飾符。 – OIS 2009-01-14 03:31:08

2

當使用正則表達式,它通常更高性能的使用的更具體的表達,而不是「懶點」,這通常會導致過度的回溯。您可以使用負前瞻,以達到同樣的效果,而不負擔過重的正則表達式引擎:

$find_players = preg_match("/<!--PLAYER=((?:[^-]+|-(?!->))*)-->/ig", $html_content, $match); 

你要知道,這是不可能的使用懶點會造成明顯的問題,一個簡單的情況就是這樣,但它是一個好習慣總是告訴正則引擎究竟是你的意思。在這種情況下,您希望收集儘可能多的字符(「貪婪」)而不傳遞註釋終止符。終止符是一個破折號,後面是另一個破折號和一個大於號的符號。所以,我們允許任何數量的任何字符除了破折號或破折號不要開始註釋終止符。