Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6941163
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T12:51:01+00:00 2026-05-27T12:51:01+00:00

EDIT: I selected ridgerunner’s answer as it contained the information needed to solve the

  • 0

EDIT: I selected ridgerunner’s answer as it contained the information needed to solve the problem. But I also felt like adding a fully fleshed-out solution to the specific question in case someone else wants to fully understand the example too. You will find it somewhere below.

This question is about clarifying the behavior of php’s regex engine for recursive expressions. (If you ideas for how to properly match the strings below without using recursive php regex, that’s very cool, but that’s not the question.)

a(?:(?R)|a?)a

This is a simple expression that aims to match the character “a” or nothing, nested in one or multiple nests of the character “a”. For instance, aa, aaa, aaaa, aaaaa. You don’t need to use recursion for this:

aa*a

would work great. But the point is to use recursion.

Here is a piece of code you can run to test my failing pattern:

<?php
$tries=array('a','aa','aaa','aaaa','aaaaa','aaaaaa');
$regex='#a(?:(?R)|a?)a#';
foreach ($tries as $try) {
echo $try." : ";
if (preg_match($regex,$try,$hit)) echo $hit[0]."<br />";
else echo 'no match<br />';
}
?>

In the pattern, two “a”s are framing an alternation. In the alternation, we either match a recursion of the whole pattern (two “a”s framing an alternation), or the character “a”, optionally empty.

In my mind, for “aaaa”, this should match “aaaa”.

But here is the output:

a : no match
aa : aa
aaa : aaa
aaaa : aaa
aaaaa : aaaaa
aaaaaa : aaa

Can someone explain what is happening on the third and fifth lines of output?
I have tried tracing the path that I imagine the engine must be taking, but I must be imagining it wrong. Why is the engine returning “aaa” as a match for “aaaa”? What makes it so eager? I must be imagining the matching tree in the wrong order.

I realise that

#(?:a|a(?R)a)*#

kind of works, but my question is why the other pattern doesn’t.

Thanks heaps!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T12:51:01+00:00Added an answer on May 27, 2026 at 12:51 pm

    Excellent (and difficult) question!

    First, with the PCRE regex engine, the (?R) behaves like an atomic group (unlike Perl?). Once it matches (or doesn’t match), the matching that happened inside the recursive call is final (and all backtracking breadcrumbs saved within the recursive call are discarded). However, the regex engine does save what was matched by the whole (?R) expression, and can give it back and try the other alternative to achieve an overall match. To describe what is happening, lets change your example slightly so that it will be easier to talk about and keep track of what is being matched at each step. Instead of: aaaa as the subject text, lets use: abcd. And lets change the regex from '#a(?:(?R)|a?)a#' to: '#.(?:(?R)|.?).#'. The regex engine matching behavior is the same.

    Matching regex: /.(?:(?R)|.?)./ to: "abcd"

    answer = r'''
    Step Depth Regex          Subject  Comment
    1    0     .(?:(?R)|.?).  abcd     Dot matches "a". Advance pointers.
               ^              ^
    2    0     .(?:(?R)|.?).  abcd     Try 1st alt. Recursive call (to depth 1).
                     ^         ^
    3    1     .(?:(?R)|.?).  abcd     Dot matches "b". Advance pointers.
               ^               ^
    4    1     .(?:(?R)|.?).  abcd     Try 1st alt. Recursive call (to depth 2).
                     ^          ^
    5    2     .(?:(?R)|.?).  abcd     Dot matches "c". Advance pointers.
               ^                ^
    6    2     .(?:(?R)|.?).  abcd     Try 1st alt. Recursive call (to depth 3).
                     ^           ^
    7    3     .(?:(?R)|.?).  abcd     Dot matches "d". Advance pointers.
               ^                 ^
    8    3     .(?:(?R)|.?).  abcd     Try 1st alt. Recursive call (to depth 4).
                     ^            ^
    9    4     .(?:(?R)|.?).  abcd     Dot fails to match end of string.
               ^                  ^    DEPTH 4 (?R) FAILS. Return to step 8 depth 3.
                                       Give back text consumed by depth 4 (?R) = ""
    10   3     .(?:(?R)|.?).  abcd     Try 2nd alt. Optional dot matches EOS.
                        ^         ^    Advance regex pointer.
    11   3     .(?:(?R)|.?).  abcd     Required dot fails to match end of string.
                           ^      ^    DEPTH 3 (?R) FAILS. Return to step 6 depth 2
                                       Give back text consumed by depth3 (?R) = "d"
    12   2     .(?:(?R)|.?).  abcd     Try 2nd alt. Optional dot matches "d".
                        ^        ^     Advance pointers.
    13   2     .(?:(?R)|.?).  abcd     Required dot fails to match end of string.
                           ^      ^    Backtrack to step 12 depth 2
    14   2     .(?:(?R)|.?).  abcd     Match zero "d" (give it back).
                        ^        ^     Advance regex pointer.
    15   2     .(?:(?R)|.?).  abcd     Dot matches "d". Advance pointers.
                           ^     ^     DEPTH 2 (?R) SUCCEEDS.
                                       Return to step 4 depth 1
    16   1     .(?:(?R)|.?).  abcd     Required dot fails to match end of string.
                           ^      ^    Backtrack to try other alternative. Give back
                                        text consumed by depth 2 (?R) = "cd"
    17   1     .(?:(?R)|.?).  abcd     Optional dot matches "c". Advance pointers.
                        ^       ^      
    18   1     .(?:(?R)|.?).  abcd     Required dot matches "d". Advance pointers.
                           ^     ^     DEPTH 1 (?R) SUCCEEDS.
                                       Return to step 2 depth 0
    19   0     .(?:(?R)|.?).  abcd     Required dot fails to match end of string.
                           ^      ^    Backtrack to try other alternative. Give back
                                        text consumed by depth 1 (?R) = "bcd"
    20   0     .(?:(?R)|.?).  abcd     Try 2nd alt. Optional dot matches "b".
                        ^      ^       Advance pointers.
    21   0     .(?:(?R)|.?).  abcd     Dot matches "c". Advance pointers.
                           ^    ^      SUCCESSFUL MATCH of "abc"
    '''
    

    There is nothing wrong with the regex engine. The correct match is abc (or aaa for the original question.) A similar (albeit much longer) sequence of steps can be made for the other longer result string in question.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a button like this <input type=button id=btnEdit value=Edit Selected class=emrBTN style=top:5;right:95;width:100; visibility:hidden
((Answer selected - see Edit 5 below.)) I need to write a simple pink-noise
Edit: This question was written in 2008, which was like 3 internet ages ago.
Edit: From another question I provided an answer that has links to a lot
Edit: I have solved this by myself. See my answer below I have set
I want to allow users edit Flex AdvancedDataGrid selected row by button click instead
I wants to block virtual keyboard from opening when all text selected in edit
How do I edit the selected text of a textarea form element? EDIT: as
Edit: Doh! The reason it was unable to be selected was because the bundle
EDIT: This question was originally about checkboxes, but I am getting the same behavior

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.