2010-01-25 46 views
4

我不知道,如果其中之一是「好」,然後其他的,爲什麼會是這樣,但我有一個看起來像這樣的原始字符串:使用後視或捕捉組是更好嗎?

$string = '/random_length_user/file.php'; 

現在,有兩種方法與之相匹配的,第一,用我的新朋友,查找後面,第二,沒有:

preg_match("%(?<=^/)([^/]*)%", $string, $capture); 
preg_match("%^/([^/]*)%", $string, $capture); 

他們返回,依次是:

Array 
(
    [0] => random_length_user 
) 
Array 
(
    [0] => /random_length_user 
    [1] => random_length_user 
) 

基本上我得到的結果我想要進來$ capture [0]使用look-behind,而$ capture [1]不使用。現在的問題是......是否有理由選擇這些方法之一?

回答

1

問題在於,後視方法不夠靈活;當你開始處理可變長度匹配時,它會下降。例如,假設你想在你的例子中提取文件名,並且你不知道目錄的名字。捕獲組技術仍然正常工作:

preg_match("%^/\w+/([^/]*)%", '/random_length_user/file.php'); 

Array 
(
    [0] => /random_length_user/file.php 
    [1] => file.php 
) 

...但後視方法不,因爲後視表達式只能匹配固定數量的字符。但是,還有一個更好的選擇:\K,MATCH POINT RESET運算符。無論你把它放在哪裏,正則表達式引擎都會假裝真正開始的比賽。所以,你得到的結果,你會與一個回顧後,不使用固定長度的限制相同:

preg_match('%^/\w+/\K[^/]+$%', '/random_length_user/file.php'); 

Array 
(
    [0] => file.php 
) 

據我所知,這個功能只適用於Perl的5.10+和工具(如PHP的preg_功能)由PCRE庫供電。對於PCRE參考,請參閱the manpage並搜索(F3)\K

3

它可能與preg_match沒有什麼區別,但使用preg_replace時它會很重要,因爲它會影響將被替換的內容。

它也可能是一個問題,當你做一個全球性的比賽,因爲捕獲組將消耗字符,而lookarounds不會

簡單的例子:

  • /(?<=a)a/g'aaaa'Array('a', 'a', 'a')
  • /(a)a/g'aaaa'給出Array('aa', 'aa')