2013-10-04 29 views
1

輸入:如何從URL中刪除backpath/parentpath?

http://foo/bar/baz/../../qux/ 

所需的輸出:

http://foo/qux/ 

這可以使用正則表達式來實現(除非有人可以建議一種更有效的替代方案)。雖然我不熟悉與如何做一個向後查找第一個「/」(即

/\.\.\/[^\/]+/ 

如果是正向查找,這將是一樣簡單。沒有做/[a-z0-9-_]+\/\.\./)。

我想到的其中一個解決方案是使用strrev,然後應用正向查找正則表達式(第一個示例),然後執行strrev。雖然我確信有更有效的方法。

+0

注意,/ [^ \ /] + /匹配/../ – Qsebas

+0

@Qsebas這是真的 - 如果可以假定輸入格式正確,這將不會是一個問題,但真正... –

回答

0

不是我見過的最清晰的問題,但如果我理解你的要求,我想你只需要切換你身邊有什麼這樣的:

/[^\/]+/\.\./ 

...然後更換與一/

做,直到沒有替換由你應該有你想要什麼

編輯

你嘗試似乎試圖匹配正斜槓/和兩個點\.\.後跟斜槓/(或\/ - 他們應該都匹配同樣的事情),那麼一個或多個非斜槓字符[^/]+,用斜線/終止。翻轉它,你想要找到一個斜線,後跟一個或多個非斜線字符和一個終止斜線,然後是兩個點和一個最終斜線。

您可能會困惑於認爲正則表達式引擎解析並消耗事物(因此您不希望消耗沒有正確數量的點的目錄名稱),但這並不是這樣通常是有效的 - 在替換或返回任何東西之前,正則表達式引擎匹配整個表達式。所以,你可以有兩個點,一個目錄名,或者一個目錄名,後面跟兩個點 - 它對引擎沒有影響。

如果您嘗試使用斜槓封閉的Perl風格的語法,那麼您當然需要使用\/來匹配任何你想匹配的斜槓,比如中間的那個,但是我也會推薦匹配和替換封閉在URL斜槓,以及:我認爲PHP會像

preg_replace('/\/[^\/]+\/\.\.\//', '/', $input) 

(??)

0

從技術上講,你要什麼做的是取代「/path1/path2/../段'/'由'/'做什麼需要做的是匹配'pathx /'^ n'../'^ n這不是一個正則表達式(Context Free Lenguaje)...但是大多數的Regex圖書館支持一些非常規的圖書館,並且可以(通過很多努力)管理這些類型的圖書館。

一個簡單的方法來解決它留在正則表達式和循環數次,通過'

更換「/[^./]+/../」如果你仍然在一個單一的做一步,先行和分組是需要的,但它會很難寫吧,(我不這麼用的,但我會努力)

編輯:

我已經找到了解決辦法只有1 REGEX ...但應該使用PCRE正則表達式

([^/.]+/(?1)?\.\./) 

我根據我的如下因素鏈路上的解決方案: Match a^n b^n c^n (e.g. "aaabbbccc") using regular expressions (PCRE)

(注意點是在第一部分「禁止」,你不能有path.1/path.2 /如果你whant到相當多複雜,因爲你必須承認他們,而是禁止「../」在首節

這個子表達式是admiting路徑的名字,如‘路徑1 /’

[^/.]+/ 

這個子表達式是admiting爲有效雙點。

\.\./ 

您可以在測試正則表達式 https://www.debuggex.com/ (記得設置它PCRE模式)

這裏有一個工作副本: https://eval.in/52675

0

您應該能夠使用這個代碼:

$url = 'http://foo/bar/baz/../../qux/'; 
$url_parts = parse_url($url); 
$path = $url_parts['path']; 
while(strstr($path, '..')) 
    $path = preg_replace('~[^/]*/\.{2}/~', '', $path); 
$url_parts['path'] = $path; 
$canoicalUrl = http_build_url(null, $url_parts); 

echo $canoicalUrl; 

輸出:

http://foo/qux/