布尔搜索运算符优化,尊重引用的术语

时间:2014-02-26 17:39:36

标签: php mysql wordpress

寻找解析复杂搜索字符串的最佳方法,并将其缩减为在术语之间使用1个布尔运算符。运算符是OR,AND,NOR。

例: 1. OR AND NOR NOR AND AND Fred OR NOR AND Wilma NOR AND AND Barney OR“AND AND AND Flintstones”OR AND NOR NOR AND AND

OR AND NOR和AND AND Fred OR NOR AND Wilma NOR和AND Barney OR“和AND Flintstones”OR和NOR NOR AND AND(Mar-05-2014添加)

结果:

Fred OR Wilma NOR Barney OR" The and AND Flintstones"

注意:我正在寻找PHP代码实现。

2 个答案:

答案 0 :(得分:1)

您最好的选择是逐字阅读输入并在状态机中处理。

有些事情:

define("STATE_DEFAULT", 0); // we're in regular text
define("STATE_OPERATOR", 1);  // we found operator (AND|OR|NOR)
define("STATE_QUOTE",2); // we're inside quoted text

$input = 'OR AND NOR NOR AND AND Fred OR NOR AND Wilma NOR AND AND Barney OR "The and AND Flintstones" OR AND NOR NOR AND AND';

// check if a word is an operator... used in multiple places 
function _is_op($word) { return preg_match("/^(AND|OR|NOR)$/i", $word); }

$words = explode(" ", $input);
$words_count = count($words);
$state = STATE_DEFAULT;

for($i=0; $i<$words_count; ++$i)
{
    $word = $words[$i];

    switch($state)
    {
         case STATE_QUOTE:
             if(substr($word,-1)=='"') $state = STATE_DEFAULT;
             break;

         case STATE_OPERATOR:
             if(_is_op($word))
             {
                 unset($words[$i]);
                 break;
             }

         case STATE_DEFAULT:
         default:
            $state = STATE_DEFAULT;
             if($word[0] == '"')
                 $state = STATE_QUOTE;
             elseif(_is_op($word))
                 $state = STATE_OPERATOR;
             break;
    }
}

// if we removed some words, count()-1 is no longer the last element
$words = array_values($words);

// strip operators from start and end
if(_is_op($words[0])) array_shift($words);
if(_is_op($words[count($words)-1])) array_pop($words);

$output = implode(" ", $words);

虽然使用正则表达式可能会这样做,但它很复杂且难以管理。

答案 1 :(得分:0)

Hope this will help:

$words = explode (" ", 'OR AND NOR NOR AND AND Fred OR NOR AND Wilma NOR AND AND Barney OR "The and AND Flintstones" OR AND NOR NOR AND AND');

$arrayOperators = array('OR', 'AND', 'NOR');

$flag = false;
foreach($words as $key => $word){
    if($flag && in_array($word, $arrayOperators)){
          unset($words[$key]);
    }elseif(in_array($word, $arrayOperators)){
       if($key != 0){
          $resultArray[] = $word;
        }
        $flag = true;

    }else{
        $resultArray[] = $word;
        $flag = false;
    }
}
end($resultArray);
$lastKey = key($resultArray);
if(in_array($resultArray[$lastKey], $arrayOperators)){
   array_pop($resultArray);
}

var_dump(implode(' ', $resultArray));

<强>结果:

string(53) "Fred OR Wilma NOR Barney OR "The and AND Flintstones""