php preg_match可选子模式

时间:2012-12-12 07:48:15

标签: php regex preg-match-all

我尝试构建一个从html模板中捕获变量的小系统。

变量定义为@XX @并且可能(但不是必需)具有使用冒号(:)发送的额外参数,即@ XXX @:j以json编码的形式发送数据。

我设法做的是创建一个preg_match_all来捕获变量和那些额外的参数。所以我想出了这个preg:

preg_match_all("/(@.*@(?:(j|n|x|z))?)/imU", $string,$this->localVariables,PREG_PATTERN_ORDER);

j | n | x | z是可能的可用的额外参数。

我发送给$ string的字符串是: @ geterr @@ domain @:j @ jhon @:n

我从preg_match_all获得的结果是:

Array
(
[0] => Array
    (
        [0] => @geterr@
        [1] => @domain@
        [2] => @jhon@
    )

[1] => Array
    (
        [0] => @geterr@
        [1] => @domain@
        [2] => @jhon@
    )

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

)

我知道(或者我认为我知道)?:用于可选的子模式 我使用的修改是: 我不区分大小写 m允许我的字符串是多行的 你 - 不贪心

我不知道自己做错了什么。

任何帮助都应该得到很大的帮助

1 个答案:

答案 0 :(得分:4)

您的模式中存在一些问题/(@.*@(?:(j|n|x|z))?)/imU

  1. 在整个模式中你不需要一个捕捉小组。

  2. ?:正在创建非捕获组,但不限于可选组。

  3. 修饰符m被称为multiline,但这有点误导,它仅影响锚点^$以匹配起点和终点一行,而不仅仅是字符串。

    你想要的是修饰符ssingleline修饰符。它将整个字符串视为一行,并影响.以匹配换行符。

  4. 修饰符U使你的整个正则表达不合适。这不是你想要的,因为它也会影响你的可选组,因为它在模式的末尾永远不会匹配。

  5. 您需要匹配字符串中的:

    所以我会删除U,并在其后添加?,仅使第一个量词不合理。

  6. 所以我认为你的正则表达应该是:

    /@(.*?)@(?::(j|n|x|z))?/is
    

    这会将第一部分放在第一个捕获组中的@和第二个组中的参数之间。

    here on Regexr