Я пытаюсь сделать расширенный поиск с тегами, которые могут связывать определенные ключевые слова с такими полями, как:
поиск: статус тестового сообщения: закрыто пользователь: 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;
}
Вот альтернативное решение, но я уверен, что это самый элегантный, если мы можем сделать это с помощью регулярного выражения, я просто не могу понять шаблон:
$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++;
}
yoursite.com?search=test message&status=closed&user=john