PHP regex to split content following specific pattern

Viewed 71

I'm trying to write a regex in php to split the string to array. The string is

#000000 | Black #ffffff | White #ff0000 | Red

there can or cannot be space between the character and

|

so the regex needs to work with

#000000|Black #ffffff|White #ff0000|Red

For the second type of string this works.

$str = preg_split('/[\s]+/', $str);

How can I modify it to work with the first and second both strings?

Edit: Final output needs to be

Array ( [0] => Array ( [0] => #000000 [1] => Black ) [1] => Array ( [0] => #ffffff [1] => White ) [2] => Array ( [0] => #ff0000 [1] => Red) )
2 Answers

You need to split two times first using this regex,

'/ (?=#)/'

and then using this regex,

'/\s*\|\s*/'

Here is a php code,

$str = "#000000|Black #ffffff|White #ff0000|Red";
$str = preg_split('/ (?=#)/', $str);
for ($i = 0;$i<sizeOf($str);$i++) {
    $str[$i] = preg_split('/\s*\|\s*/', $str[$i]);
}
print_r($str);

This gives following output,

Array
(
    [0] => Array
        (
            [0] => #000000
            [1] => Black
        )

    [1] => Array
        (
            [0] => #ffffff
            [1] => White
        )

    [2] => Array
        (
            [0] => #ff0000
            [1] => Red
        )

)

For this string "#ff0000|#ff0000" it gives following output, which is what you want.

Array
(
    [0] => Array
        (
            [0] => #ff0000
            [1] => #ff0000
        )

)

I recommend just generating a single flat map of color names to hexadecimal values. Here is a way to do this with a single call to preg_split. We can try splitting on the following regex pattern:

\s*\|\s*|\s+(?=#)

This says to split on either \s*\|\s* or \s+(?=#), which is whitespace where what follows is the hash from a hexadecimal color literal.

$input = "#000000 | Black #ffffff | White #ff0000 | Red";
$array = preg_split("/\\s*\\|\\s*|\\s+(?=#)/", $input);

$map = array();
for ($i=0; $i < count($array); $i+=2) {
    $map[$array[$i]] = $array[$i+1];
}

print_r($map);

Array ( [#000000] => Black [#ffffff] => White [#ff0000] => Red )

I did not give the exact output you expect, but I also don't see any reason to have any array of associate arrays. If you really need that, then use this code:

$input = "#000000 | Black #ffffff | White #ff0000 | Red";
$array = preg_split("/\s*\|\s*|\s+(?=#)/", $input);

$output = array();
for ($i=0; $i < count($array); $i+=2) {
    $map = array();
    $map[$array[$i]] = $array[$i+1];
    $output[count($output)] = $map;
}

print_r($output);

Array ( [0] => Array ( [#000000] => Black ) [1] => Array ( [#ffffff] => White )
    [2] => Array ( [#ff0000] => Red ) )
Related