dongpu9481 2012-12-12 07:48
浏览 27
已采纳

php preg_match可选子模式

i try to build a small system that catches variables from html template.

the variables defined as @XXX@ and may (but not required) to have extra parameters that are sent with colon (:), i.e. @XXX@:j to send the data as json encoded.

what i manage to do is to create a preg_match_all to capture the variables and those extra parameters. so i came up with this preg:

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

j|n|x|z are the avialiable extra parameters that are possible.

the string that i send to $string is: @geterr@ @domain@:j @jhon@:n

the result i get from preg_match_all is:

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

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

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

)

i know (or think i know) that ?: is used for optional sub pattern the modifires iv'e used are: i for case insensitive m for to allow my string to be multiline U - to be non greedy

i have no other clue what i do wrong.

any help shall be greatly appriciated

  • 写回答

1条回答 默认 最新

  • dpnru86024 2012-12-12 08:12
    关注

    There are some issues in your pattern /(@.*@(?:(j|n|x|z))?)/imU

    1. You don't need a capturing group around the whole pattern.

    2. ?: is creating a non capturing group, it is not limited to optional groups.

    3. The modifier m is called multiline, but this is a bit misleading it affects only the anchors ^ and $ to match also the start and end of a row and not only of the string.

      What you want is the modifier s, the singleline modifier. It treats the whole string as one line, and affects the . to match also newline characters.

    4. The modifier U makes your whole regex ungreedy. This is not what you want, because it affects also your optional group and because it is at the end of the pattern it will never match.

    5. You need to match the : in your string

      So I would remove U and make only the first quantifier ungreedy, by adding a ? after it.

    So I think your regex should be:

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

    This would put the first part between the @ in the first capturing group and the parameter in the second group.

    See it here on Regexr

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!