PHP preg_split с двумя разделителями, если разделитель не находится в кавычках

Далее из моего предыдущего вопроса о preg_split который был очень быстрым, благодаря нику; Я действительно хотел бы расширить сценарий, чтобы не разбить строку, когда разделитель находится в кавычках. Например:

Если у меня есть строка foo = bar AND bar=foo OR foobar="foo bar" , я бы хотел разбить sting на каждое пространство или = символ, но включил символ = в возвращаемом массиве (который отлично работает сейчас) но я не хочу разделить строку, либо разделители заключены в кавычки.

У меня это до сих пор:

 <!doctype html> <?php $string = 'foo = bar AND bar=foo'; $array = preg_split('/ +|(=)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); ?> <pre> <?php print_r($array); ?> </pre> 

Который получает меня:

 Array ( [0] => foo [1] => = [2] => bar [3] => AND [4] => bar [5] => = [6] => foo ) 

Но если я изменил строку на:

 $string = 'foo = bar AND bar=foo OR foobar = "foo bar"'; 

Мне бы очень понравился массив:

 Array ( [0] => foo [1] => = [2] => bar [3] => AND [4] => bar [5] => = [6] => foo [6] => OR [6] => foobar [6] => = [6] => "foo bar" ) 

Обратите внимание, что "foo bar" не был разделен на пространство, потому что это в кавычках?

На самом деле не уверен, как это сделать в RegEx, или если есть даже лучший способ, но вся ваша помощь будет очень оценена!

Спасибо всем заранее!

Related of "PHP preg_split с двумя разделителями, если разделитель не находится в кавычках"

Я смог сделать это, добавив цитируемые строки в качестве разделителя a-la

 "(.*?)"| +|(=) 

Выбранная часть будет снята. Похоже, это немного незначительно, и я не тестировал его широко, но он по крайней мере работает на вашем примере.

Пытаться

 $array = preg_split('/(?: +|(=))(?=(?:[^"]*"[^"]*")*[^"]*$)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 

 (?=(?:[^"]*"[^"]*")*[^"]*$) 

part – это утверждение lookahead, удостоверяющее, что в строке есть четное число символов кавычек, поэтому оно будет терпеть неудачу, если текущая позиция находится между кавычками:

 (?= # Assert that the following can be matched: (?: # A group containing... [^"]*" # any number of non-quote characters followed by one quote [^"]*" # the same (to ensure an even number of quotes) )* # ...repeated zero or more times, [^"]* # followed by any number of non-quotes $ # until the end of the string ) 

Но зачем мешать расщеплению?

После взгляда на этот старый вопрос это простое решение приходит на ум, используя preg_match_all а не preg_split . Мы можем использовать это простое регулярное выражение, чтобы указать, что мы хотим:

 "[^"]*"|\b\w+\b|= 

Смотрите онлайн-демонстрацию .