PCRE条件子模式:(R)作为条件

时间:2013-01-11 20:58:13

标签: php regex pcre

这是关于PCRE条件子模式的PHP manual

  

条件子模式的两种可能形式是:
  (?(condition)yes-pattern)
  (?(condition)yes-pattern|no-pattern)

只要条件是数字或断言,那就没问题。但我不太明白以下

  

如果条件是字符串(R),则满足递归   调用模式或子模式已经完成。在“顶级”,   条件是假的。 (...)如果条件不是数字序列   或(R),它必须是一个断言。

如果有人可以解释一个例子条件子模式中的(R)以及如何使用它,我将不胜感激。提前谢谢。

3 个答案:

答案 0 :(得分:3)

作为一个额外和更清晰的答案...

2天前我正在编写一个匹配IPv4地址的模式,我发现自己在条件下使用递归,所以我认为我应该分享(因为它比想象的例子更有意义)。

~
(?:(?:f|ht)tps?://)?            # possibly a protocol
(
    (?(R)\.)                    # if it\'s a recursion, require a dot
    (?:                         # this part basically looks for 0-255
        2(?:[0-4]\d|5[0-5])
        | 1\d\d
        | \d\d?
    )
)(?1){3}                        # go into recursion 3 times
                                # for clarity I\'m not including the remaining part
~xi

答案 1 :(得分:1)

根据我的理解(从递归中作为子模式中的条件),这是一个非常基本的例子。

$str = 'ds1aadfg346fgf gd4th9u6eth0';
preg_match_all('~(?(R).(?(?=[^\d])(?R))|\d(?R)?)~'
/*
(?                          # [begin outer cond.subpat.]
    (R)                     # if this is a recursion               ------> IF
    .                       # match the first char
    (?                      # [begin inner cond.subpat.]
        (?=[^\d])           # if the next char is not a digit
            (?R)            # reenter recursion
    )                       # [end inner cond.subpat.]
    |                       # otherwise                             -----> ELSE
    \d(?R)?                 # match a digit and enter recursion (note the ?)
)                           # [end outer cond.subpat.]
*/
,$str,$m);
print_r($m[0]);

输出:

Array
(
    [0] => 1aadfg
    [1] => 34
    [2] => 6fgf gd
    [3] => 4th
    [4] => 9u
    [5] => 6eth
    [6] => 0
)

我知道这是一个愚蠢的例子,但我希望这是有道理的。

答案 2 :(得分:0)

(R)代表递归。这是使用它的一个很好的例子。

Recursive patterns

我不确定我曾见过(?R)用作条件,甚至是可以使用的情况,或者至少不是我理解的情况。但是你每天都在编程中学习新东西。

它可以非常容易地用作 true或false 语句。

按照这个:

< (?: (?(R) \d++  | [^<>]*+) | (?R)) * >

在false语句中使用(?R)的位置。 它与尖括号中的文本匹配,允许任意嵌套。嵌套括号中只允许使用数字(即递归时),而外层允许任何字符。

我知道这不是你要找的答案....你现在已经派我去研究这个了。