这个正则表达式的表达方式有什么问题?

时间:2014-09-23 04:57:44

标签: php regex

我想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
    )
)

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

4 个答案:

答案 0 :(得分:1)

您正在重复第二个捕获组:

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

在每次重复外部非捕获组时,内部捕获组的内容被覆盖,这就是为什么只保留最后一个匹配的原因。这是所有正则表达式引擎的标准行为。

答案 1 :(得分:0)

(?=(^.*$)|(?:\/(.*?)(?:\/|})))

试试这个。看看演示。

http://regex101.com/r/lS5tT3/3

答案 2 :(得分:0)

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

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

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

然后,生成$matches数组(preg_match()的第三个参数):

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

答案 3 :(得分: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
)