2013-06-27 75 views
1

我正在尝试制作自定义搜索查询分析器。这个想法是,用户可以编写特定的关键字以便通过例如搜索。艺术家,色彩和风格。例如,如果用户搜索:PHP - 自定义查询分析器

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"之间的空间,但我不wan't这一点。

我的问题如何通过少使用正则表达式来解决这个问题。

+1

你不想使用正则表达式的原因是什么? – PeeHaa

+0

我很困惑,你想做一些类似于谷歌搜索的东西,是吗?就像你可以搜索'php“mysql”site:stackoverflow.com“,其中MySQL将是主要必需的词和PHP的旁词或类似的东西? – Prix

+1

为什么不在你的语法中引入像';'这样的分隔符?示例查询'样式:浮雕一些关键字;颜色:#333333;艺术家:“汤姆汉克”'.. – nifr

回答

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); 
+0

谢谢,这按预期工作。 – fnky

+0

不客气。 – Timothy