2012-11-06 48 views
2

我嘗試建立正則表達式驗證(的preg_match)一些路徑字符串爲以下兩個規則:檢查目錄路徑範圍和「..」向上目錄簽署

  1. 路徑必須由來自給定的範圍[a-zA-z0-9-_\///\.]只有符號
  2. 道路不會由一個備份目錄序列 「..」

這是一個正確的路徑例如:/user/temp

和壞的一個:/../user

UPD: /user/temp.../foo也將是正確的(感謝勞倫斯·貢薩爾維斯

+0

'/ user/foo..bar/baz'認爲有效嗎? –

+0

是的,..foo/bar,/foo..bar/baz是正確的路徑示例,謝謝你的提示! – sharp

+0

更新了我的答案。 – raina77ow

回答

2

考慮一下:

$right_path = '/user/temp'; 
$wrong_path = '/../user'; 
$almost_wrong_path = 'foo/abc../bar'; 
$almost_right_path = 'foo/../bar'; 

$pattern = '#^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$#'; 
var_dump(preg_match($pattern, $right_path)); // 1 
var_dump(preg_match($pattern, $wrong_path)); // 0 
var_dump(preg_match($pattern, $almost_wrong_path)); // 1 
var_dump(preg_match($pattern, $almost_right_path)); // 0 

其實我已經建立了這個格局三個步驟:

1)給出的第一條規則是隻允許字符串中的符號爲0-9,a-zA-Z,_(下劃線),-(連字符),.(點)和兩個斜線(/\)。

[-\w.\\/] 

這裏注意兩件事情:1)連字符應該是第一或在字符類中的最後一個符號(否則就前三的位置可以用一個快捷方式(\w),則需要一個字符類來表示視爲用於定義範圍的元字符); 2)點和正斜槓都沒有被轉義(反斜線被轉義;儘管如此,它太強大了,不能單獨使用,即使在[...]子表達式中也是如此)。

2)現在我們必須確保模式確實覆蓋整個字符串。我們用所謂的錨點 - ^開始字符串,$結束。而且,不要忘記我們的字符串可能包含一個或多個允許的符號(用+量詞表示)。所以圖案變成這樣:

^[-\w.\\/]+$ 

3)最後一件事 - 我們必須避免使用../..\(由/\之前 - 與否,如果..[/\\]序列開始的字符串)也是如此。

表達這一規則的最簡單的方法是使用所謂的「negative lookahead」測試。它的內(?!...)子表達式編寫的,(在這種情況下)記載了下述理念:「確保零個或多個符號該序列後面沒有‘砍伐兩個點斜槓’序」:

^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$ 

最後一件事實際上是將圖案爲preg_match功能:當我們使用正則表達式中/符號,我們可以只選擇另一組分隔符。在我的示例中,我選擇了「#」:

$pattern = '#^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$#'; 

請參閱?這很容易。 )你必須從小事做起,逐步發展。

+0

謝謝,對於優秀的解釋) – sharp