Intereting Posts
Как перейти к изменению WordPress «Страницы Добавить новый экран» Преобразование одномерного массива в многомерный связанный массив используйте cURL для получения заголовка HTTP и сохранения в переменной Передать переменную из jQuery в PHP PHP-выборка из базы данных и сохранение в выпадающем меню html Как правильно использовать `.user.ini` -файл в PHP? Как включить уведомления на моем сервере разработки Будет ли этот SQL вызвать какие-либо проблемы? Вставка нескольких строк сразу с помощью подготовленных операторов Корпус выключателя с тремя параметрами? Почему моя функция GET моего API REST не возвращает никакого значения? Как успешно отправить электронное письмо в контактную форму через CodeIgniter? Определение внешних ключей Laravel с фабриками моделей, от одного до одного и от одного до многих отношений без создания ненужных моделей добавить функцию обмена в выбранный jquery wordpress показ сообщения по $ _POST в wordpress

строка в массив, разделенная на одиночные и двойные кавычки

Я пытаюсь использовать php для разбиения строки на компоненты массива с помощью " или ' в качестве разделителя. Я просто хочу разбить на внешнюю строку. Вот четыре примера и желаемый результат для каждого:

 $pattern = "?????"; $str = "the cat 'sat on' the mat"; $res = preg_split($pattern, $str); print_r($res); /*output: Array ( [0] => the cat [1] => 'sat on' [2] => the mat )*/ $str = "the cat \"sat on\" the mat"; $res = preg_split($pattern, $str); print_r($res); /*output: Array ( [0] => the cat [1] => "sat on" [2] => the mat )*/ $str = "the \"cat 'sat' on\" the mat"; $res = preg_split($pattern, $str); print_r($res); /*output: Array ( [0] => the [1] => "cat 'sat' on" [2] => the mat )*/ $str = "the 'cat \"sat\" on' the mat 'when \"it\" was' seventeen"; $res = preg_split($pattern, $str); print_r($res); /*output: Array ( [0] => the [1] => 'cat "sat" on' [2] => the mat [3] => 'when "it" was' [4] => seventeen )*/ 

так как вы можете видеть, что я хочу разделить только внешнюю цитату, и я хочу игнорировать любые цитаты внутри цитат.

ближайший, который я придумал для $pattern – это

 $pattern = "/((?P<quot>['\"])[^(?P=quot)]*?(?P=quot))/"; 

но, очевидно, это не работает.

Solutions Collecting From Web of "строка в массив, разделенная на одиночные и двойные кавычки"

Вы можете использовать preg_split с опцией PREG_SPLIT_DELIM_CAPTURE . Регулярные выражения не так элегантны, как обратный подход @Jan Turoň, потому что требуемая группа захвата испортила результаты.

 $str = "the 'cat \"sat\" on' the mat the \"cat 'sat' on\" the mat"; $match = preg_split("/('[^']*'|\"[^\"]*\")/U", $str, null, PREG_SPLIT_DELIM_CAPTURE); print_r($match); 

Для этого можно использовать только preg_match :

 $str = "the \"cat 'sat' on\" the mat"; $pattern = '/^([^\'"]*)(([\'"]).*\3)(.*)$/'; if (preg_match($pattern, $str, $matches)) { printf("[initial] => %s\n[quoted] => %s\n[end] => %s\n", $matches[1], $matches[2], $matches[4] ); } 

Это печатает:

 [initial] => the [quoted] => "cat 'sat' on" [end] => the mat 

Вот объяснение регулярного выражения:

  • /^([^\'"]*) => поместить начальный бит до первой котировки (одиночной или двойной) в первой захваченной группе
  • (([\'"]).*\3) => захватить в \ 2 текст, соответствующий исходной кавычки (одно или двойной) (которая фиксируется в \ 3) до закрывающей цитаты (которая должна быть одинаковой тип как открывающая цитата, следовательно, \ 3). Тот факт, что регулярное выражение является жадным по своей природе, помогает получить от первой цитаты до последней, независимо от того, сколько цитат внутри.
  • (.*)$/ => Захват до конца в \ 4

Еще одно решение, использующее preg_replace_callback

 $result1 = array(); function parser($p) { global $result1; $result1[] = $p[0]; return "|"; // temporary delimiter } $str = "the 'cat \"sat\" on' the mat 'when \"it\" was' seventeen"; $str = preg_replace_callback("/(['\"]).*\\1/U", "parser", $str); $result2 = explode("|",$str); // using temporary delimiter 

Теперь вы можете array_map эти массивы с помощью array_map

 $result = array(); function zipper($a,$b) { global $result; if($a) $result[] = $a; if($b) $result[] = $b; } array_map("zipper",$result2,$result1); print_r($result); 

И результат

 [0] => the [1] => 'cat "sat" on' [2] => the mat [3] => 'when "it" was' [4] => seventeen 

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

Вы можете использовать обратные ссылки и модификатор ungreedy в preg_match_all

 $str = "the 'cat \"sat\" on' the mat 'when \"it\" was' seventeen"; preg_match_all("/(['\"])(.*)\\1/U", $str, $match); print_r($match[0]); 

Теперь у вас есть свои внешние цитаты

 [0] => 'cat "sat" on' [1] => 'when "it" was' 

И вы можете найти остальную часть строки с помощью substr и strpos (вид решения Blackbox)

 $a = $b = 0; $result = array(); foreach($match[0] as $part) { $b = strpos($str,$part); $result[] = substr($str,$a,$b-$a); $result[] = $part; $a = $b+strlen($part); } $result[] = substr($str,$a); print_r($result); 

Вот результат

 [0] => the [1] => 'cat "sat" on' [2] => the mat [3] => 'when "it" was' [4] => seventeen 

Просто разделите пустой пустой заголовок / конечный элемент, если цитата находится в самом начале / конце строки.