Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP-自定义查询解析器_Php - Fatal编程技术网

PHP-自定义查询解析器

PHP-自定义查询解析器,php,Php,我正在尝试创建一个自定义搜索查询解析器。这个想法是用户可以编写特定的关键字来搜索,例如艺术家、颜色和风格。例如,如果用户搜索: 风格:浮雕一些关键词颜色:#333333艺术家:“汤姆·汉克”钢铁 后端中返回的结果将是: array( "style" => "Emboss", 0 => "some", 1 => "keywords" "color" => "#333333", "artist" =>

我正在尝试创建一个自定义搜索查询解析器。这个想法是用户可以编写特定的关键字来搜索,例如艺术家、颜色和风格。例如,如果用户搜索:

风格:浮雕一些关键词颜色:#333333艺术家:“汤姆·汉克”钢铁

后端中返回的结果将是:

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"
)
数组
(
[0]=>一些
[1] =>字符串
[2] =>与
[3] =>但是:“一些字符串”
)
如果
but:
某个字符串之间有空格,它就可以工作,但是我不希望这样


我的问题是如何通过使用更少甚至没有正则表达式来解决这个问题。

试试这个。。。这是一个快速而肮脏的过程代码,但它可以满足您的需要。您需要对其进行重构以使其可维护

<?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);

你不想使用regex的原因是什么?我很困惑,你想做一些像谷歌在搜索中做的事情,是吗?比如你可以搜索
php“mysql”站点:stackoverflow.com
,其中mysql将是主要的必要单词和php的副词,或者类似的东西?你为什么不引入一个像
这样的分隔符呢在您的语法中?示例查询<代码>样式:浮雕一些关键字;颜色:#333333;艺术家:“汤姆·汉克”
。@nif分隔符(如
)对任何人来说都不是直观的,也许除了程序员。此外,关键字是彼此独立的实体,除非
给出了类型,并且
允许空格。@类人主义是你曾经听过别人告诉你的还是从个人经验中听到的?说真的,你想要的只是regex的尖叫声。你不会因为任何性能问题而受到伤害(如果有的话,它太小了以至于无法注意到)。