how to split a string containing numbers in our outside parenthesis using preg_match_all

Question!

I have a string that looks something like this:

535354 345356 3543674 34667 2345347 -3536 4532452 (234536 2345634 -4513453) (2345 -13254 13545)

The text between () is always at the end of the string (at least for now).

i need to split it into an array similar to this:

[0] => [0] 535354,345356,3543674,34667,2345347,-3536,4532452
[1] => [0] 234536,2345634,-4513453
    => [1] 2345,-13254,13545

What expression should i use for preg_match_all? Best i could get with my limited knowledge is /([0-9]{1,}){1,}.*(?=(\(.*\)))/U but i still get some unwanted elements.



Answers

You may use a regex that will match chunks of numbers outside of parentheses and those inside with "~(?<=\()\s*$numrx\s*(?=\))|\s*$numrx~" where a $numrx stands for the number regex (that can be enhanced further).

The -?\d+(?:\s+-?\d+)* matches an optional -, 1 or more digits, and then 0+ sequences of 1+ whitespaces followed with optional - and 1+ digits. (?<=\()\s*$numrx\s*(?=\)) matches the same only if preceded with ( and followed with ).

See this PHP snippet:

$s = "535354 345356 3543674 34667 2345347 -3536 4532452 (234536 2345634 -4513453) (2345 -13254 13545)";
$numrx = "-?\d+(?:\s+-?\d+)*";
preg_match_all("~(?<=\()\s*$numrx\s*(?=\))|\s*$numrx~", $s, $m);
$res = array();
foreach ($m[0] as $k) {
    array_push($res,explode(" ",trim($k)));
}
print_r($res);

Output:

[0] => Array                                                                                                                                                     
    (                                                                                                                                                            
        [0] => 535354                                                                                                                                            
        [1] => 345356                                                                                                                                            
        [2] => 3543674                                                                                                                                           
        [3] => 34667                                                                                                                                             
        [4] => 2345347                                                                                                                                           
        [5] => -3536                                                                                                                                             
        [6] => 4532452                                                                                                                                           
    )                                                                                                                                                            

[1] => Array                                                                                                                                                     
    (                                                                                                                                                            
        [0] => 234536  
        [1] => 2345634                                                                                                                                           
        [2] => -4513453                                                                                                                                          
    )                                                                                                                                                            

[2] => Array                                                                                                                                                     
    (                                                                                                                                                            
        [0] => 2345                                                                                                                                              
        [1] => -13254                                                                                                                                            
        [2] => 13545                                                                                                                                             
    )                                                                                                                                                            


You can use this regex in preg_match_all:

$re = '/\d+(?=[^()]*[()])/';

RegEx Demo

RegEx Breakup:

\d+       # match 1 or more digits
(?=       # lookahead start
   [^()]* # match anything but ( or )
   [()]   # match ( or )
)         # lookahead end
By : anubhava


The key word that you're apparently missing is "epsilon." If you search on Python epsilon value then it returns a links to StackOverflow: Value for epsilon in Python near the top of the results in Google.

Obviously it helps if you understand how the term is associated with this concept.



This video can help you solving your question :)
By: admin