php预匹配可选子模式

php预匹配可选子模式,php,regex,preg-match-all,Php,Regex,Preg Match All,我试图构建一个从html模板捕获变量的小系统 定义为@XXX@的变量可能需要但不需要使用冒号发送的额外参数,即@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是可行的额外参数 我

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

定义为@XXX@的变量可能需要但不需要使用冒号发送的额外参数,即@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表示允许我的字符串是多行的 U-不贪婪

我不知道我做错了什么


任何帮助都将受到极大的感谢

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

你不需要一个围绕整个模式的捕获组

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

修饰符m被称为multiline,但这有点误导,因为它只影响锚定“^和$”以匹配行的开始和结束,而不仅仅是字符串

您需要的是修饰符s,单线修饰符。它将整个字符串视为一行,并影响。也匹配换行符

修饰符U使整个正则表达式变为ungreedy。这不是您想要的,因为它也会影响您的可选组,并且因为它位于模式的末尾,它将永远不会匹配

您需要匹配字符串中的:

所以我会去掉U,只让第一个量词ungreedy,加上a?在它之后

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

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


请看

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

你不需要一个围绕整个模式的捕获组

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

修饰符m被称为multiline,但这有点误导,因为它只影响锚定“^和$”以匹配行的开始和结束,而不仅仅是字符串

您需要的是修饰符s,单线修饰符。它将整个字符串视为一行,并影响。也匹配换行符

修饰符U使整个正则表达式变为ungreedy。这不是您想要的,因为它也会影响您的可选组,并且因为它位于模式的末尾,它将永远不会匹配

您需要匹配字符串中的:

所以我会去掉U,只让第一个量词ungreedy,加上a?在它之后

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

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


看到它了吗?定义它前面的字符可能出现也可能不出现{0,1}是否存在/@.@j|n | x | z?/imU work?>>?定义该字符不仅仅是一个字符。它可能是整个子模式,比如[a-z]?谢谢nryls。我们需要这个吗?既然它是可选的,就在@符号之间?定义它前面的字符可能出现也可能不出现{0,1}是否存在/@.@j|n | x | z?/imU work?>>?定义该字符不仅仅是一个字符。它可能是整个子模式,比如[a-z]?谢谢nryls。我们需要这个吗?在@符号之间,因为它是可选的为什么我没有看到[jnxz]在这个模式中使用?为什么我没有看到[jnxz]在这个模式中使用?
/@(.*?)@(?::(j|n|x|z))?/is