Search code examples
phpregexpreg-split

Split a string on a dynamic placeholder with preg_split() and retain the delimiting placeholder


I need help on regular expression here.

I want PHP to be able to split a string in sections of arrays such that a substring enclosed by <%me %> will be in its own slot.

So for example,

Hi there how are <%me date(); %> => {"Hi there how are ", "<%me date(); %>} 
Hi there how are you<%me date(); %> => {"Hi there how are you", "<%me date(); %>}
Hi there how are you<%me date(); %>goood => {"Hi there how are you", "<%me date(); %>, "good"
Hi there how are you<%me date(); %> good => {"Hi there how are you", "<%me date(); %>}, " good"}

Note the white space won't stop the tags from getting parsed in.


Solution

  • On capturing the splitting delimiter in PREG

    You can use PREG_SPLIT_DELIM_CAPTURE to split on and capture the delimiter.

    Remember to put the delimiter in a capturing group (…) for this to work properly.

    Here's an example:

    $text = 'abc123xyz456pqr';
    
    $parts = preg_split('/(\d+)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
    
    print_r($parts);
    

    This prints (as seen on ideone.com):

    Array
    (
        [0] => abc
        [1] => 123
        [2] => xyz
        [3] => 456
        [4] => pqr
    )
    

    References


    Back to the question

    In this case, you can try the delimiter pattern (<%me[^%]+%>). That is:

    • <%me, literally
    • [^%]+, i.e. anything but %
    • %>, literally
    • The whole thing captured in group 1

    If % can appear in the tag, then you can try something like (<%me.*?%>).

    Here's an example:

    $text = 'prefix<%me date() %>suffix';
    
    $parts = preg_split('/(<%me[^%]+%>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
    
    print_r($parts);
    

    The above prints (as seen on ideone.com):

    Array
    (
        [0] => prefix
        [1] => <%me date() %>
        [2] => suffix
    )
    

    Related questions