user3741635
user3741635

Reputation: 862

How to form two arrays from string separated by "," and followed by -?

$str="a,b,c,d-e,f,g,h"

I am trying to extract the strings from $str that are separated "," and are before "-" in one array and the strings separated by "," and are after "-" in second array. So that $arr1=array(a,b,c,d); and $arr2=array(e,f,g,h);. I am just using $str as an example and generally I want this to work for any string of the same form i.e. $str=s1,s2,s3,s4,s5,....-r1,r2,t3....

NOTE: If $str doesn't have "-" then $arr2 vanishes and $arr1 contains an array of the elements separated by ',' in $str.

This is what I tried

preg_match_all('~(^|.*,)(.*)(,.*|\-|$)~', $str, $arr1);
preg_match_all('~(-|.*,)(.*)(,.*|$)~', $str, $arr2);

However each array comes with one element that contains the string str. Does anyone know why this is not working.

Upvotes: 3

Views: 86

Answers (4)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

Without regex (the most reasonable way):

$str="a,b,c,d-e,f,g,h";

list($arr1, $arr2) = explode('-', $str);

$arr1 = explode(',', $arr1);

if ($arr2)
    $arr2 = explode(',', $arr2);
else
    unset($arr2);

With regex (for the challenge):

if (preg_match_all('~(?:(?!\G)|\A)([^-,]+)|-?([^,]+),?~', $str, $m)) {
    $arr1 = array_filter($m[1]);
    if (!$arr2 = array_filter($m[2]))
        unset($arr2);
}

Upvotes: 0

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626806

All of your regex patterns are not optimal and it seems the task is easier to solve with explode and array_map:

array_map() returns an array containing all the elements of array1 after applying the callback function to each one. The number of parameters that the callback function accepts should match the number of arrays passed to the array_map()

$str="a,b,c,d-e,f,g,h";
$ex = array_map(function ($s) {
       return explode(",", $s);
    }, explode("-", $str));
print_r($ex);

See IDEONE demo

Results:

Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
            [2] => c
            [3] => d
        )

    [1] => Array
        (
            [0] => e
            [1] => f
            [2] => g
            [3] => h
        )

)

Upvotes: 3

Narendrasingh Sisodia
Narendrasingh Sisodia

Reputation: 21437

You can simply use preg_match to check does your string contains - if yes than can simply use array_walk like as

$str = 'a,b,c,d-e,f,g,h';
$result = [];
if(preg_match('/[-]/', $str)){
    array_walk(explode('-',$str),function($v,$k)use(&$result){
        $result[] = explode(',',$v);
    });
}else{
    array_walk(explode(',',$str),function($v,$k)use(&$result){
        $result[] = $v;
    });
}
print_r($result);

Upvotes: 2

vks
vks

Reputation: 67968

^(.*?(?=-|$))|(?<=-)(.*$)

You can use this to get 2 arrays.See demo.

https://regex101.com/r/vV1wW6/19

Your regex is not working as you have used greedy modifier..*, will stop at the last instance of ,

EDIT:

Use this is you want string after - to be in second group.

^(.*?(?=-|$))(?:-(.*$))?

https://regex101.com/r/vV1wW6/20

Upvotes: 2

Related Questions