我正在尝试制作自定义搜索查询解析器。该想法是用户可以编写特定关键字以通过例如搜索来搜索。艺术家,颜色和风格。例如,如果用户搜索:
style:Emboss some keywords color:#333333 artist:"Tom Hank" steel
后端返回的结果是:
array(
"style" => "Emboss",
0 => "some",
1 => "keywords"
"color" => "#333333",
"artist" => "Tom Hank", // Note the word is not broken
2 => "steel"
)
到目前为止,我已经设法做了oppersite - 通过从数组构建一个查询字符串没有问题。但是我将字符串解析为数组时遇到问题 - 主要是因为有引号这样的事实。
到目前为止我是
public function parseQuery($str) {
$arr = array();
$pairs = str_getcsv($str, ' '); // This bugs me
foreach($pairs as $k => $v) {
list($name, $value) = explode(":", $v, 2);
if(!isset($value)) {
$arr[] = $name;
} else {
$arr[$name] = $value;
}
}
return $arr;
}
问题依赖于str_getcsv
函数,如果第一个引号之间或最后一个引号之间没有空格,它会中断引用的单词。它像这样打破它
Array
(
[0] => Some
[1] => string
[2] => with
[3] => but:"some <--- This is the sinner
[4] => string"
)
如果but:
和"some string"
之间有空格,它会起作用,但我不会这样。
我的问题是如何通过使用较少或不使用正则表达式来解决这个问题。
答案 0 :(得分:3)
试试这个...它是快速而又脏的程序代码,但是做你想要的。你将重构它以使其可维护。
<?php
$str = 'style:Emboss some keywords color:#333333 artist:"Tom Hank" steel';
$pos = 0;
$buffer = '';
$len = strlen($str);
$quote = false;
$key = '';
$arr = array();
while ($pos < $len) {
switch ($str[$pos]) {
case '"':
$quote = !$quote;
break;
case ':':
$key = $buffer;
$buffer = '';
break;
case ' ':
if ($quote) {
$buffer .= $str[$pos];
}
elseif (!empty($key)) {
$arr[$key] = $buffer;
$key = '';
$buffer = '';
}
else {
$arr[] = $buffer;
$buffer = '';
}
break;
default:
$buffer .= $str[$pos];
}
$pos++;
}
if (!empty($key)) {
$arr[$key] = $buffer;
}
else {
$arr[] = $buffer;
}
print_r($arr);