Расширенный поиск на основе тегов

0

Я пытаюсь сделать расширенный поиск с тегами, которые могут связывать определенные ключевые слова с такими полями, как:

поиск: статус тестового сообщения: закрыто пользователь: john

Удивительно, что лучше всего разбирать строку в приятном массиве:

["search" => "test message", "status" => "closed", "user" => "john"]

В настоящий момент я делаю это так:

$parse = explode(':', $_REQUEST['q']);
$parsed = [];
foreach($parse AS $key => $value) {
  if($key == (count($parse) - 1))
   break;
  $next = explode(' ', $parse[($key + 1)]);
  $last = array_pop($next);
  $next = implode(' ', $next);
  $parse[($key + 1)] = $last;
  $parsed[$parse[$key]] = !empty($next) ? $next : $last;
}
  • 0
    Я думаю, было бы намного проще, если бы ваш клиент отправил строку запроса с уже разделенными параметрами: yoursite.com?search=test message&status=closed&user=john
  • 0
    Это не проблема. Я могу сделать выше анализ в JS при отправке. Я хочу найти лучший способ разбора строки на пары тег / значение. Желательно так, как это делают Apple, Google в своих приложениях электронной почты, например. Способ, который будет работать в любых условиях. Я не уверен, что это решение будет работать очень хорошо.
Показать ещё 3 комментария
Теги:

1 ответ

0

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

$string = "search: test message status: closed user: john";
$pieces = explode(' ', $string);
$values = array();
$array = array();
foreach ($pieces as $piece) {
    if (strpos($piece, ":") !== false) {
        if (count($values)) {
            $array[$key] = join(" ", $values);
        }
        $key = rtrim($piece, ":");
        $values = array();
    } else {
        $values[] = $piece;
    }
}
$array[$key] = join(" ", $values);
var_dump($array);

Вывод

array
  'search' => string 'test message' (length=12)
  'status' => string 'closed' (length=6)
  'user' => string 'john' (length=4)

РЕДАКТИРОВАТЬ

На основе комментария tntu, вот версия с регулярным выражением:

$string = "search: test message status: closed user: john";
$matches = array();
preg_match_all('/(([a-z]+):([a-z0-9 ]+(?![a-z:])))+/is', $string, $matches);
$i = 0;
foreach ($matches[2] as $key) {
    if (isset($matches[3][$i])) {
        $array[$key] = trim($matches[3][$i]);
    } else {
        break;
    }
    $i++;
}
  • 0
    / (([az] +): ([a-z0-9] + (?! [az:]))) + / is
  • 0
    ах, круто благодарю вас.
Показать ещё 3 комментария

Ещё вопросы

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