2015-10-06 113 views
5

我要檢查 'N' 爆炸字符串:PHP preg_match_all,檢查和爆炸

{$gallery#pager/collectionName/imageName/manual/no_effect/foo1/foo2/.../fooN} 

到:

var_name[0] => 'gallery', 
modul_name[0] => 'pager', 
3[0] => 'collectionName', 
4[0] => 'imageName', 
5[0] => 'manual' 
... 
N[0] => 'fooN' 

我做了如下正則表達式:

/{\$(?P<var_name>[^#]+)#(?P<module_name>[^\/]+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+))?)?)?)?)?}/ 

,但它太難看,只支持五個參數。 請幫我做一個遞歸部分來提取所有參數。

PS:是的,我可以拆分這VAR_NAMEMODULE_NAMEparamters部分,那麼我可能會爆炸參數部分由 '/',但我不喜歡它。

回答

3

你可以使用preg_split()

正則表達式:

preg_split('@([$#])|[{}/][email protected]', $text) 

並丟棄所述陣列中的第一和第三項。

ideone Demo



編輯:以反映OP的意見(不是問題)指定的新條件:應該驗證語法^\{\$\w+#\w+(?:/\w*)$和記號化的變種,模塊參數獨立。

正則表達式:

~\G(?(?=^)\{\$(\w++)#(\w++)(?=[\w/]+}$))/\K\w*+~ 

代碼:

// http://stackoverflow.com/q/32969465/5290909 

$pattern = '@\G(?(?=^)\{\$(\w++)#(\w++)(?=[\w/]+}$))/\K\w*[email protected]'; 
$text = '{$gallery#pager/collectionName/imageName/manual/no_effect/foo1/foo2/fooN}'; 

$result = preg_match_all($pattern, $text, $matches); 

if ($result === 0) { 
    // is invalid, does not match '~^\{\$\w+#\w+(?:/\w*)+$~' 
    echo "Invalid text"; 
} else { 
    // Assign vars (only to clarify) 
    $module_name = array_pop($matches)[0]; 
    $var_name = array_pop($matches)[0]; 
    $parameters = $matches; 

    echo "VAR NAME: \t'$var_name'\nMODULE: \t'$module_name'\nPARAMETERS:\n"; 
    print_r($matches); 
} 

輸出:

VAR NAME: 'gallery' 
MODULE:  'pager' 
PARAMETERS: 
Array 
(
    [0] => collectionName 
    [1] => imageName 
    [2] => manual 
    [3] => no_effect 
    [4] => foo1 
    [5] => foo2 
    [6] => fooN 
) 

ideone Demo

+0

對,但不驗證它。 –

+0

請指明您的問題確切需要驗證的內容 – Mariano

+0

'{$ var_name#module_name}' - 需要此格式。參數是可選的:'{$ var_name#module_name/arg1/arg2 /.../ argN}'所有名字和值(var名稱,模塊名稱,參數)都可以用\ w +來檢查。 –

2
{\$([^#]+)#|\G(?!^)([^\/]+)\/|\G(?!^)(.*?)}$ 

你可以簡單地做一個匹配,而不是抓住groups。看演示。

https://regex101.com/r/cJ6zQ3/18

$re = "/{\\$([^#]+)#|\\G(?!^)([^\\/]+)\\/|\\G(?!^)(.*?)}$/m"; 
$str = "{\$gallery#pager/collectionName/imageName/manual/no_effect/foo1/foo2/.../fooN}"; 

preg_match_all($re, $str, $matches); 
+0

1)超,THX。我將使用'{\ $([^#] +)#([^ \ /] +)| \ G(?!^)(\/[^ \ /] +)}',因爲var_name($ 1)和module_name($ 2)是必需的。 2/a)匹配[3]從1開始索引。爲什麼? 2/b)這是什麼\ G(?!^)?我無法谷歌這一點。 :( –