I am trying to make an advanced search with tags that can associate specific keywords to specific fields like so:
search: test message status: closed user: john
Wondering what is the best way to parse the string into a nice array like so:
["search" => "test message", "status" => "closed", "user" => "john"]
At the moment I am doing it like this:
$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;
}
Here is an alternative solution, but I am preatty sure, that is most elegant if we could do it with regexp, I've just can't figure out the pattern:
$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);
Output
array
'search' => string 'test message' (length=12)
'status' => string 'closed' (length=6)
'user' => string 'john' (length=4)
EDIT
Based on tntu comment, here is a version with regex:
$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++;
}