2

This is from the PHP manual regarding PCRE conditional subpatterns:

The two possible forms of conditional subpattern are:
(?(condition)yes-pattern)
(?(condition)yes-pattern|no-pattern)

That's OK as long as the condition is a digit or an assertion. But I don't quite understand the following

If the condition is the string (R), it is satisfied if a recursive call to the pattern or subpattern has been made. At "top level", the condition is false. (...) If the condition is not a sequence of digits or (R), it must be an assertion.

I would be grateful if someone could explain on an example what (R) is in conditional subpattern and how to use it. Thanks in advance.

inhan
  • 7,394
  • 2
  • 24
  • 35
Placido
  • 1,386
  • 1
  • 12
  • 24
  • 2
    http://stackoverflow.com/questions/4840988/the-recognizing-power-of-modern-regexes <-- there are quite thorough explanations there – fge Jan 12 '13 at 00:25

3 Answers3

3

As an additional and clearer answer…

2 days ago I was writing a pattern to match an IPv4 address and I found myself using the recursion in condition so I thought I should share (because it makes more sense than imaginative examples).

~
(?:(?: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
inhan
  • 7,394
  • 2
  • 24
  • 35
  • Thanks! Although the same can be easily achieved without conditionals. You just need to remove `(?(R)\.)` and replace `(?1){3}` with `(?:\.(?1)){3}` – Placido Jan 24 '13 at 12:22
  • You could have a nested conditional subpattern in the recursion, though. – inhan Jan 24 '13 at 14:22
  • Yes, thank you! Your example is much closer to the real world than the previous ones. – Placido Jan 24 '13 at 14:49
1

From what I understand (from the recursion as the condition in a subpattern) here's a very basic example.

$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]);

And the output:

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

I know this is a silly example but I hope it makes sense.

inhan
  • 7,394
  • 2
  • 24
  • 35
0

The (R) stands for recursion. Here is a good example of using it.

Recursive patterns

Not sure I have ever seen (?R) used as the condition, or even a situation where that would be usable, or at least not in my understanding. but you learn new stuff every day in programming.

It could be used very easily as the true or false statement.

as per this:

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

Where as (?R) is used in the false statement. Which matches text in angle brackets, allowing for arbitrary nesting. Only digits are allowed in nested brackets (that is, when recursing), whereas any characters are permitted at the outer level.

I know this is not the answer you are looking for.... You have now sent me on a quest to research this.

ROY Finley
  • 1,406
  • 1
  • 9
  • 18
  • I know what (R) is. Could you please explain how can I use it in conditional subpatterns (that was the original question)? – Placido Jan 12 '13 at 09:05
  • Here is a great example explained perfectly: [Recursive R](http://stackoverflow.com/a/8442349/1880925) – ROY Finley Jan 12 '13 at 13:22
  • This is not what I'm lookung for. I'm trying to clarify for myself how to use recursion as a condition - (?(R)true|false). – Placido Jan 12 '13 at 13:52
  • Out of curiosity, what is with `\d++` and `[^<>]*+`? – inhan Jan 13 '13 at 04:35
  • 1
    @inhan [possessive quantifiers](http://www.regular-expressions.info/possessive.html) – Wiseguy Jan 13 '13 at 04:52
  • @Wiseguy Thank you. It amazes me to discover something new each day about Regex rules. I'll sure read that. – inhan Jan 13 '13 at 04:55
  • Thanks! Although I can't see any practical use for this regex it makes some sense - something like "match a tag containing any characters with any number of nested tags containing only digits". – Placido Jan 16 '13 at 22:05