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" не был разделен на пространстве, потому что он в кавычках?



Действительно не знаю, как это сделать в регулярном выражении, или если есть даже лучший способ, но вся ваша помощь будет очень признательна!



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

794   3  

3 ответов:

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

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

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

Попробуйте

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

The

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

Часть-это утверждение 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|=

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

Comments

    Ничего не найдено.