Мне нужно разделить строку запятыми и пробелами, но игнорировать внутренние кавычки, одинарные кавычки и круглые скобки
$str = "Questions, \"Quote\",'single quote','comma,inside' (inside parentheses) space #specialchar";
так что результирующий массив будет иметь
[0] Вопросы [1] Цитата [2] Одиночная цитата [3] запятая, внутри [4] внутри круглых скобок [5] пространство [6] #specialchar
мое текущее регулярное выражение
$tags = preg_split("/[,\s]*[^\w\s]+[\s]*/", $str,0,PREG_SPLIT_NO_EMPTY);
но это игнорирует специальные символы и разделяет запятые внутри кавычек, результирующий массив:
[0] Вопросы [1] Цитата [2] Одиночная цитата [3] запятой [4] внутри [5] внутри круглых скобок [6] пространство [7] SPECIALCHAR
ps: это не csv
Большое спасибо
Это будет работать только для не вложенных круглых скобок:
$regex = <<<HERE / " ( (?:[^"\\\\]++|\\\\.)*+ ) \" | ' ( (?:[^'\\\\]++|\\\\.)*+ ) \' | \( ( [^)]* ) \) | [\s,]+ /x HERE; $tags = preg_split($regex, $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
++
и *+
будут потреблять столько, сколько они могут, и ничего не вернуть для возврата. Этот метод описан в perlre (1) как наиболее эффективный способ выполнения такого соответствия.
Ну, это работает для данных, которые вы предоставили:
$rgx = <<<'EOT' / [,\s]++ (?=(?:(?:[^"]*+"){2})*+[^"]*+$) (?=(?:(?:[^']*+'){2})*+[^']*+$) (?=(?:[^()]*+\([^()]*+\))*+[^()]*+$) /x EOT;
Взгляды утверждают, что если есть какие-либо двойные кавычки, одинарные кавычки или круглые скобки перед текущей совпадающей позицией, существует четное число из них, а парны находятся в сбалансированных парах (допускается не вложенность). Это быстрый и грязный способ убедиться, что текущее совпадение не встречается внутри пары котировок или парен.
Конечно, он предполагает, что вход хорошо сформирован. Но что касается четко сформулированной ситуации, то как избежать кавычек в кавычках? Что делать, если у вас есть цитаты внутри parens или наоборот? Будет ли этот ввод легальным?
«не цитата», «не а) цитата» (не «,»)
Если это так, перед вами впереди намного труднее.