preg_split is not breaking the strings in the array

Asked

Viewed 182 times

5

I’m not getting to use the function preg_split() correctly.

I’m trying to break a string array() via regex but it’s not happening.

$string = "<:termo.9:><:termo.10:><:termo.11:>";
$res = preg_split("/(<:)(nome|termo)(.)(\d+)(:>)/", $string,-1,PREG_SPLIT_DELIM_CAPTURE);

The value attributed to $res is:

        Array ( 
          [0] => 
          [1] => <: 
          [2] => termo 
          [3] => . 
          [4] => 9 
          [5] => :> 
          [6] => 
          [7] => <: 
          [8] => termo 
          [9] => . 
          [10] => 12 
          [11] => :> 
          [12] => 
          [13] => <: 
          [14] => termo 
          [15] => . 
          [16] => 10 
          [17] => :> 
          [18] => 
          [19] => <: 
          [20] => termo 
          [21] => . 
          [22] => 11 
          [23] => :> 
        )

And I’d actually like to:

Array (
           [0] => "<:termo.9:>"
           [1] => "<:termo.10:>"
           [2] => "<:termo.11:>"
       )

A palliative solution would be to use the following Pattern:

$res = preg_split("/(<:nome\.\d+:>|<:termo\.\d+:>)/", $string,-1,PREG_SPLIT_DELIM_CAPTURE);

And the $res sai:

Array ( 
          [0] => 
          [1] => <:termo.9:> 
          [2] => 
          [3] => <:termo.12:> 
          [4] => 
          [5] => <:termo.10:> 
          [6] => 
          [7] => <:termo.11:> 
          [8] => 
          [9] => <:termo.9:> 
          [10] => 
        )

But if you look closely, the conditions imposed are:

(<:nome\.\d+:>|<:termo\.\d+:>)

And the variations of nomenclatures that I can use can increase, like:

<:name.2:>, <:text.4:>,<:code.5:>,etc

and this way the code would not be "optimized", say so.

What could be wrong in Pattern for it to be improved?

  • 1

    Have you tried putting in the 4th parameter preg_split_delim_capture?

  • @Wallacemaxters really returned the array breaking the String, but broke every condition of the pattern. Ex: Array([0]=>"<:",[1]=>"nome",[2]=>"."...etc)

  • It is practically impossible to do this using the preg_split, because, this function looks for specific references to split the code. It’s practically an improved version of explode, if I may say so.

  • @Edilson I think I understand better now. Maybe the solution I need is not to use preg_split .

2 answers

3

The problem is not quite the pattern, the function preg_split, searching for the pattern to break the string into parts, that is to say it is similar to explode, however, in it you can define an explosion pattern that is not limited to the same sequence always.

Example

$string = "teste_de_explosão-de-string";
$res = preg_split('/_|-/', $string); // vai explodir por '_' e por '-'

In your case it would be a capture and not an explosion, and for that can be used the preg_match_all.

In your case

$string = "<:termo.9:><:termo.10:><:termo.11:>";
preg_match_all("/(<:(nome|termo)\.\d+:>)/", $string, $res);

To recover previously grouped values, use:

foreach($res[1] as $id=>$val){
    $arr[] = $val;  
}

print_r($arr);

Obs

To capture . literal in REGEX should escape the same \., for he represents anything.

  • Helped Parties what I need, because I really needed a explode using a condition regex. But the patter who instructed above improved my situation.

  • Ah, the preg_match_all basically does this.

  • It took a little longer to test the function to understand it. I think that’s it! Thank you very much!

2


$foo = "<:termo.9:><:termo.10:><:termo.11:><:nome.2:><:text.4:><:codigo.5:>";

preg_match_all("/<:[a-z]+\.[0-9]+:>/s", $foo, $bar);

print_r($bar);

Will return:

Array
(
    [0] => Array
        (
            [0] => <:termo.9:>
            [1] => <:termo.10:>
            [2] => <:termo.11:>
            [3] => <:nome.2:>
            [4] => <:text.4:>
            [5] => <:codigo.5:>
        )

)
  • I guess that’s it.. rsrs. Thanks!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.