Greetings. I work with lines like /command param1 param2 , and to split the line I just used explode by space. But now it became necessary to work with such lines: /command "some long text" param2 . That is, I also need to break the gap, but do not take into account the spaces inside the quotes. How will this be implemented correctly? The ultimate goal is to get an array in which the command and parameters will be separately.

    2 answers 2

    This can be done using regular expressions:

     preg_match_all("/\"(.*?)(?:\"|$)|([\S]+)/u", $input, $output); 

    $output[0] will contain the required array

    http://www.phpliveregex.com/p/hEV

    • Thank you very much. Could you explain a little bit what does (.*?) Mean? Why not easy .* ? - Nik
    • one
      Look, my answer was not quite correct, I corrected a little. About ? - in this case ? cancels the quantifier's greed, otherwise .* simply eats the entire line. - Crantisz
    • and what to eat .*? ? And for what .*? put in brackets? - Nik
    • one
      The first part to the vertical line eats everything from quotation marks to quotation marks or end of line. Therefore, for each parameter in quotes, there are 2 matches - from quotation marks to quotation marks or from quotation marks to the end. If you bet ? he turns off greed and eats the least. It’s not possible to make a whole non greedy option The second part of the expression should be greedy. Well, it’s not necessary to put brackets in principle, and so it works, you can remove everything at all preg_match_all("/\".*?\"|$|[\S]+/", $input_lines, $output_array); . but in $output[1] you have expressions in quotes, $output[2] without. - Crantisz

    Quick crutch

     $str = 'command "some long text" param2 "this is a test yo" param3'; $exp = explode(' ', $str); $newArr = []; $isQuotes = false; $str = ''; foreach ($exp as $item) { if (substr($item, 0, 1) == '"') $isQuotes = true; if (substr($item, -1) == '"') { $isQuotes = false; if (!empty($str)) $str .= ' '.$item; } if ($isQuotes) { $str .= ' '.$item; } else { array_push($newArr, !empty($str) ? $str : $item); $str = ''; } } 

    Conclusion:

     Array ( [0] => command [1] => "some long text" [2] => param2 [3] => "this is a test yo" [4] => param3 )