2014-09-23 68 views
1

我想的preg_match下面的代码:这个正则表达式有什么问题?

{{{/foo:bar/a/0/b}}} 

这是我的正则表达式(它不工作,我不明白为什么):

|{{{\/([[:alpha:]][[:alnum:]\_]*\:[[:alpha:]][[:alnum:]\_]*)(?:\/([[:alnum:]\_]*))+}}}|Uism 

预期结果:

Array (
[0] => Array 
    (
     [0] => {{{/foo:bar/a/0/b}}} 
    ) 

[1] => Array 
    (
     [0] => foo:bar 
    ) 

[2] => Array 
    (
     [0] => a 
    ) 

[3] => Array 
    (
     [0] => 0 
    ) 

[4] => Array 
    (
     [0] => b 
    ) 
) 

结果我得到:

Array (
[0] => Array 
    (
     [0] => {{{/foo:bar/a/0/b}}} 
    ) 

[1] => Array 
    (
     [0] => foo:bar 
    ) 

[2] => Array 
    (
     [0] => b 
    ) 
) 

我只收到最后一个元素。那么它有什么问题?

+0

修饰符'i','s'和'm'在这里没用。 – 2014-09-23 05:15:14

回答

1

你重复该第二捕获组:

(?: 
\/ 
(
    [[:alnum:]\_]* 
) 
)+ 

在外非捕获组的每个重复中,内捕获组的内容被改写,这是原因为什么只保留最后一场比赛?这是所有正则表达式引擎的标准行为。

0

同一个捕获组的每个后续匹配都会覆盖前一个;这就是为什么最终只有b

我在这种情况下会建议先匹配整个块,然后使用更简单的explode()来挖掘内部数据;使用这个表达式:

|{{{\/([[:alpha:]][[:alnum:]\_]*\:[[:alpha:]][[:alnum:]\_]*(?:\/[[:alnum:]\_]*)+)}}}|U 

然后,用所得$matches阵列(第三个参数preg_match()):

$data = explode('/', $matches[1]); 
0

你的模式是什么完整的矫枉过正,应该是很简单的:

$rex = "@[{]{3}/(\w+:\w+)/(\w)/(\d)/(\w)[}]{3}@"; 
$str = "{{{/foo:bar/a/0/b}}}"; 

preg_match($rex, $str, $res); 

结果:

Array 
(
    [0] => {{{/foo:bar/a/0/b}}} 
    [1] => foo:bar 
    [2] => a 
    [3] => 0 
    [4] => b 
) 
相关问题