Marks Polakovs
Marks Polakovs

Reputation: 508

Regex split position before and after match

I'm trying to split a string using PHP preg_split that contains tags in the form [fbes_keep]...[/fbes_keep].

The regex I have is (?=\[\/?fbes_(remove|keep)]) (regex101 link)

My input is

[fbes_keep]hello[/fbes_keep][fbes_remove]goodbye[/fbes_remove]

The code I'm using is $fragments = preg_split( '@(?=\[\/?fbes_(remove|keep)])@i', $original );

What I want is for the splits to be like this: (where a | character is a split, with added spaces for readability)

[fbes_keep] | hello | [/fbes_keep] | [fbes_remove] | goodbye | [/fbes_remove]

But the splits I'm getting are:

[fbes_keep]hello | [/fbes_keep] | [fbes_remove]goodbye | [/fbes_remove]

What do I need to change?

Upvotes: 2

Views: 279

Answers (3)

WEBjuju
WEBjuju

Reputation: 6581

Use preg_match_all and loop over the matches for more organization and flexibility in using the results:

   $str = '[fbes_keep]hello[/fbes_keep][fbes_remove]goodbye[/fbes_remove]';
    preg_match_all('@([[][^]]*[]])([^[]*)([[]/[^]]*[]])@Ui', $str, $matches);

    /*
    // die('<pre>'.print_r($matches,true));
    Array
    (
        [0] => Array
            (
                [0] => [fbes_keep]hello[/fbes_keep]
                [1] => [fbes_remove]goodbye[/fbes_remove]
            )

        [1] => Array
            (
                [0] => [fbes_keep]
                [1] => [fbes_remove]
            )

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

        [3] => Array
            (
                [0] => [/fbes_keep]
                [1] => [/fbes_remove]
            )

    )
    */

UPDATE 1

    // how many matches you have is here
    $count_of_matches = count($matches[0]);

    // to answer your comment question...get the 3 parts for match group 0
    $match_group = 0; // you also have a match_group 1
    // loop over them if you like // foreach ($matches[0] as $match_group=>$full_match) {

    // for now, loop over the match group 0's 3 outputs
    for ($i=1; $i<4; $i++) {
      echo $matches[$i][$match_group].', ';
    }
    // [fbes_keep], hello, [/fbes_keep], 

    // or access them directly
    echo "{$matches[1][0]}, {$matches[2][0]}, {$matches[3][0]}";

UPDATE 2

    // here is the full, double loop grabbing all of them
    foreach ($matches[0] as $match_group=>$full_match) {
      for ($i=1; $i<4; $i++) {
        echo $matches[$i][$match_group].', ';
      }
      echo '<br>';
    }

    /* yielding
    [fbes_keep], hello, [/fbes_keep],
    [fbes_remove], goodbye, [/fbes_remove],
    */

Upvotes: 0

RomanPerekhrest
RomanPerekhrest

Reputation: 92874

Use the following approach with preg_match_all and implode functions:

$str = '[fbes_keep]hello[/fbes_keep][fbes_remove]goodbye[/fbes_remove]';
preg_match_all("/\[\/?[a-z_]+\]|[a-z]+\b/", $str, $matches);
$result = implode(" | ", $matches[0]);

print_r($result);

The output:

[fbes_keep] | hello | [/fbes_keep] | [fbes_remove] | goodbye | [/fbes_remove]

Upvotes: 1

Maik
Maik

Reputation: 41

Have you tried $var = explode("|", $myString);?

you're trying to get the " hello " and " goodbye " values, right?

Upvotes: 1

Related Questions