What I have found so far is this
preg_match_all(\"/\'[^\']+\'|[^,]+/\", $input, $output);
Its supposed to find commas outside simple quotes, i
Not sure that your original pattern for single quotes is correct, this one will find all commas outside double quotes:
preg_match_all('~"(?:[^\\\"]+(?:\\\.)*|\\\.)*+"(*SKIP)(*F)|,~s', $subject, $matches);
pattern details:
~
"
(?: # all possible content between quotes
[^\\\"]+ # all that is not a double quote or a backslash
(?:\\\.)* # eventual escaped characters
| # OR
\\\. # an escaped character
)*+ # repeat zero or more times (possessive)
" # closing double quote, can be replaced with (?:"|\z) or "?
(*SKIP)(*F) # forces the pattern to fail and to not retry double quoted parts
| # OR
, # a comma
~
s # allow the dot to match newlines characters
Note: if you want to consider the substring after an orphan double quote as a quoted substring (until the end of the string), you can replace the closing double quote in the pattern with (?:"|\z)
or more simply "?
Note2: to reduce drastically the number of steps needed to find a match, the pattern can be rewritten like this:
~[^,"]*+\K(?:"[^"\\\]*+(?:(?:\\\.)+[^\\\"]*)*+"?|,(*ACCEPT)|\z(*COMMIT).)(*SKIP)(*F)~s
or if you want to use the first character discrimination technic:
~(?=[",])(?:"[^"\\\]*+(?:(?:\\\.)+[^\\\"]*)*+"?(*SKIP)(*F)|,)~s