2012-05-17 81 views
6

我不擅長用正則表達式,所以我甚至不知道這個做什麼失敗,正是:的preg_match在PHP> 5.3

echo preg_match('/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}){1,254}$/', 'example12345678.com>'); 

我把它從舊版本的Zend框架的 - 1.5,這是過時的,在框架的最後一個穩定版本中,此正則表達式不再提供。然而,它的行爲是好奇的,因爲我沒有在官方的php資源中找到文檔說明或後向不兼容性說明。

的事情是,在PHP 5.2 *它工作正常:返回0在PHP 5.3.10,5.4.0返回FALSE,意思是「一個錯誤(最有可能的5.3 ,5.4我相信。) 」。

我的問題是:爲什麼?什麼是錯誤?它是正則表達式,某種遞歸還是規則模糊?爲什麼它在PHP 5.2上工作,如果是這樣?


有趣的是,如果我改變「example12345678.com>」到「example1234567.com>」(使它的一個或多個字符短) - 它開始工作並返回0。如果我將其改爲「123123123123123123123123123 「它的工作原理也和返回1

UPD:還不知道,如果這事,但PCRE版本這裏有8.02(PHP 5.2)VS 8.12(PHP 5.3)


UPD2:我確實瞭解它的作用......或多或少......並且現在正在開展任何工作都沒有問題。正如我所說 - 一個Zend_Validate_ *更新解決它。換句話說,我會試着描述一下我的擔憂:

說,我升級了一個重要的軟件,使php5.2> php5.3切換。我試圖找到我可能面臨的所有問題的信息(主要通過閱讀:http://php.net/manual/en/migration53.php)。該軟件有點舊,但並不古老,例如Zend Framework可以是1.5版本。我檢查/修補/分析並修復每個bc中斷和棄用功能。即使我的單元測試運行良好。

令我驚訝的是,問題中所描述的事情發生了。 (確切地說,Zend_Validate_Hostname在那裏引發異常)。所以現在我想知道爲什麼我升級時錯過了這個,更重要的是,我是否應該在應用中嘗試各種可以想象的輸入數據以重新檢查所有'preg_match'(和其他PCRE利用函數),試圖找到類似的「錯誤修復」。

如果這是一個「錯誤修復」。因爲它看起來像一個新的錯誤 - 它曾經在php5.2中按預期工作,並且不再工作。

希望得到一些線索來縮小搜索範圍。

+1

你如何使用它,如果你不知道那是什麼,究竟? – ilanco

+0

從哪個文件中獲取? –

+0

@ilanco,我用它作爲框架的一部分。但這是不合時宜的。 – lcf

回答

2

這是一個醜陋的正則表達式。問題是,字符串可能與匹配的方式太多,因此在發現它實際上不匹配之前,引擎的內存不足會嘗試使用它們。

此外,它看起來像是試圖匹配有效的域名,而事實上並非如此。我將取代調用preg_match用這個函數的調用來代替:

function is_valid_domain_name($string) { 
    if (strlen($string) > 253) { 
     return false; 
    } 
    $label = '(?!-)[a-zA-Z0-9-]{0,63}(?<!-)'; 
    return preg_match("/^(?:$label\.){0,126}$label$/", $string); 
} 

它很快失敗對你的問題的字符串:

echo is_valid_domain_name('example12345678.com>'),"\n"; 
+0

這確實很醜。像大多數其他正則表達式:)謝謝你的回答馬克。然而,這個特定的正則表達式的問題已經解決了。我問到的是:爲什麼它使用php5.2?我用一些細節更新了我的問題。 – lcf

+0

你永遠不會在升級中抓住所有東西,不管你多麼小心。如果你碰到過觸發這個問題的測試,那麼很好,但你沒有。您只需準備好迭代並修復之後發現的問題。我猜測在pcre引擎中發生了一些變化,它設置了一個更嚴格的約束(或者可能只是一個先前不存在約束的約束)來嘗試並避免無限遞歸問題。 –

+0

你說得對,我什麼都抓不住。但我可以儘可能地抓住。而我所接觸到的東西必須有一個解釋,一個真實的東西,不只是「哦,嘆氣,運氣不好,你會怎麼做」。如果這是一個錯誤,我可以報告它,如果這是一項功能,我們可以將它添加到向後兼容性列表中。 – lcf