preg_split is not breaking the strings in the array

5

I'm not able to use the preg_split() function correctly.

I'm trying to break a String in a array() via regex but it's not rolling.

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

The value assigned 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 really 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 $res exits:

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:

  

asked by anonymous 30.09.2015 / 23:02

2 answers

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:>
        )

)
    
01.10.2015 / 15:39
3

The problem is not well with pattern , the function preg_split , looks for the pattern to break the string in parts, ie it is similar to explode , however, in it you can define an explosion pattern that does not the same sequence is always limited.

Example

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

In your case it would be a catch and not an explosion, and for that you can use preg_match_all .

In your case

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

To retrieve previously grouped values, use:

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

print_r($arr);

Obs

To catch . literal in REGEX you should escape the same \. , since it represents anything.

    
01.10.2015 / 13:46