2012-11-30 21 views
4

我正在看一些代碼,並開始考慮使用preg_replace截斷字符串(在本例中爲URI)的最有效方法。使用preg_replace截斷字符串的最有效方法?

第一關 - 我意識到,擺在首位使用preg_replace可能是矯枉過正完成這個任務,它可能是不必要的昂貴,而且它可能會更好地使用PHP的字符串友好的功能來處理諸如substr。我知道這一點。

儘管如此,考慮這兩個不同的正則表達式:

$uri = '/one/cool/uri'; // Desired result '/one/cool' 

// Using a back-reference 
$parent = preg_replace('#(.*)/.*#', "$1", $uri); 

// Using character class negation 
$parent = preg_replace('#/[^/]+$#', '', $uri); 

默認情況下,我會假設,在前者的情況下,創造了反向引用將是比不這樣做更昂貴,爲此第二個例子會更好。但是後來我開始想知道在第二個例子中使用[^/]可能比第一個例子中對應的.更昂貴,如果是這樣,還有多少?

我喜歡的第一個例子從可讀性的角度來看,因爲我們是雞蛋裏挑骨頭,我走向(以書面可讀的代碼過於畢竟,有值)兩者之間選擇它傾斜。雖然可能只是我個人的偏好。

想法?

+2

你似乎知道你在問什麼,所以爲什麼不設置一個標杆?我的直覺也假定否定是較便宜的,但那只是我的_gut_。我沒有數據支持它。製作一些數據! –

+2

注意,第二個版本可以使用佔有慾量詞(抑制回溯)會更高效:'#/ [^ /] + $#' –

回答

2

我也會測量兩個選項的運行時間。從文檔此信息可幫助過:

http://www.php.net/manual/en/regexp.reference.performance.php

如果您正在使用與不包含換行符主題串這樣的模式,通過設置PCRE_DOTALL,或者開始與該模式獲得最佳性能^。*表示顯式錨定。這節省了PCRE不必掃描主題尋找換行符以重新啓動。

因此,$parent = preg_replace('#^(.*)/.*#s', "$1", $uri);可能會加快第一個選項。第二個就不需要這個設置:

秒(PCRE_DOTALL)

如果設定了此修正,在 模式中的圓點元字符的所有字符,包括換行符相匹配。沒有它, 新行被排除在外。這個修飾符相當於Perl的/ s 修飾符。 負數類如[^ a]總是匹配換行符 字符,與此修飾符的設置無關。

+0

這隻會令對不圖案在所有匹配的字符串的差異。如果OP知道他想要截斷的每個字符串**將包含至少一個斜線,那麼無論如何該匹配都將在第一次嘗試中找到。 –

+0

建議的優化是避免使用換行符分割字符串,並嘗試每個字符串的模式。 – Niloct

+0

啊對,對不起,夠公平。我有點錯過了這一點。儘管URI很少包含換行符。但總的來說,那絕對是一個好點。 –