Получить ассоциативный массив с помощью preg_split

1

У меня есть 2 вопроса с моим ниже регулярным выражением:

1) Выход показывает 2 дополнительных (пустой) элемент в начале и конце (не может использовать PREG_SPLIT_NO_EMPTY, поскольку isbn может быть пустым).

2) Можно ли получить из этого ассоциативный массив? Я имею в виду, что я хочу, чтобы результат был представлен в виде $ output = array ("title" => "Book1", "writer" => "writer1", "isbn" => "1234") в этом формате.

$val = "[title]Book1[/title][writer]Writer1[/writer][isbn]1234[/isbn]";
$pattern = '/\[title](.*?)\[\/title].*?\[writer](.*?)\[\/writer].*?\[isbn](.*?)\[\/isbn]/i';
$allparams = preg_split($pattern, $val, -1, PREG_SPLIT_DELIM_CAPTURE);

Вывод:

Array ( [0] => [1] => Book1 [2] => Writer1 [3] => 1234 [4] => )
  • 2
    Так почему же вы используете preg_split вместо preg_match для соответствующего задания?
  • 0
    Мне нужно эти 3 элемента отдельно в массиве. Может ли preg_match достичь этого?
Показать ещё 2 комментария
Теги:
preg-split

2 ответа

2
Лучший ответ

preg_split не подходит, используйте preg_match (или preg_match_all если вы хотите получить несколько результатов из одной строки):

$pattern = '~
    \[title]  (?<title>  [^[]+ ) \[/title]  .*?
    \[writer] (?<writer> [^[]+ ) \[/writer] .*?
    \[isbn]   (?<isbn>   [^[]+ ) \[/isbn]
~sx';

if (preg_match($pattern, $yourtext, $m)) {
    echo 'title:  ' . $m['title']  . PHP_EOL
       . 'writer: ' . $m['writer'] . PHP_EOL
       . 'isbn:   ' . $m['isbn']   . PHP_EOL;
}

Флаг s позволяет точке совпадать с новыми строками, а флаг x игнорирует пробелы в шаблоне.

Обратите внимание, что вы можете отфильтровать числовые ключи с PHP 5.6, как это (не проверено):

$result = array_filter($m, function ($k) { return !is_numeric($k); }, ARRAY_FILTER_USE_KEY);

Если у вас нет PHP> = 5.6, простой цикл foreach может выполнить задание:

$result = array();
foreach ($m as $k=>$v) {
    if (is_numeric($k) || empty($v)) continue;
    $result[$k] = $v;
}
  • 0
    вау .. я не знал о таком синтаксисе регулярных выражений. Большое спасибо. И последнее: возможно ли заставить его работать, даже если некоторые элементы отсутствуют (например, нет блока [writer] [/ writer])? Поэтому я имею в виду, что все три элемента должны быть необязательными, если они найдены.
  • 0
    @AbdFahim: Вы всегда можете заключить каждый тег bbcode в необязательную группу, например так (?:\[title]...\[/title] .*?)? Title (?:\[title]...\[/title] .*?)? и т. д., но не забудьте позаботиться о том, чтобы по крайней мере одна группа существовала (возможно, вы можете начать шаблон с утверждения предвкушения, что-то вроде (?=\[) или (?=\[(?:title|writer|isbn)]) ) или, проще говоря, вы проверяете, содержит ли $m не только пустые элементы.
1

что-то подобное сделает трюк, даже если это не лучший способ, я думаю...

$a = "/\[(.*)\](.*)\[\/.*\]/U";
$val = "[title]Book1[/title][writer]Writer1[/writer][isbn]1234[/isbn]";
$array = json_decode('{'.substr(preg_replace($a, ',"$1":"$2"', $val), 1).'}');

BTW, этот находит каждую [TAG] и помещает ее в массив (всякий раз, сколько тегов вы используете). Будьте осторожны, поскольку он использует JSON, у него может быть некоторая проблема с " или неожиданной строкой не в шаблоне [tag]string[/tag].

  • 0
    Это разумно и служит цели. Спасибо, я кое-что узнал сегодня. На этот раз я пойду с решением Казимира, хотя.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню