Далее из моего предыдущего вопроса о 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, или если есть даже лучший способ, но вся ваша помощь будет очень оценена!
Спасибо всем заранее!
Я смог сделать это, добавив цитируемые строки в качестве разделителя 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|=
Смотрите онлайн-демонстрацию .