PHP从布尔搜索中分割字符串,并使用LIKE创建mysql查询


PHP split string from boolean search and create a mysql query using LIKE

给定字符串:

foo | bar &baz -bbb not nnn - ccc OR boo AND AA:BB:CC:11:22:33 OR somestring

我如何将其拆分为mysql LIKE查询?

我试过preg_match, preg_match_all, preg_split和explosion,但是我似乎无法放下。

类似:

    $ands = preg_split("/'s?&'s?|'s[Aa][Nn][Dd]'s/", $searchText);
    $ors = preg_split("/'s?'|'s?|'s[Oo][Rr]'s/", $searchText);
    $nots = preg_split("/'s?!'s?|'s?-'s?|'s+[Nn][Oo][Tt]'s+/", $searchText);
    echo "<pre>";
    echo "String = $searchText'n";
    echo "Ands:'n";
    print_r($ands);
    echo "ORs:'n";
    print_r($ors);
    echo "Nots:'n";
    print_r($nots);

但是打印出来的是:

String = foo | bar & baz -bbb not nnn - ccc OR boo AND AA:BB:CC:11:22:33 or *somestring*
Ands:
Array
(
    [0] => foo | bar
    [1] => baz -bbb not nnn - ccc OR boo
    [2] => AA:BB:CC:11:22:33 or *somestring*
)
ORs:
Array
(
    [0] => foo
    [1] => bar & baz -bbb not nnn - ccc
    [2] => boo AND AA:BB:CC:11:22:33
    [3] => *somestring*
)
Nots:
Array
(
    [0] => foo | bar & baz
    [1] => bbb
    [2] => nnn
    [3] => ccc OR boo AND AA:BB:CC:11:22:33 or *somestring*
)

我最后需要写的是:

SELECT * from tbl where msg LIKE 'foo' OR msg LIKE 'bar' AND msg LIKE 'baz' AND msg NOT LIKE 'bbb' AND msg NOT LIKE 'nnn' AND msg NOT LIKE 'ccc' OR msg LIKE 'boo' AND msg LIKE 'AA:BB:CC:11:22:33' OR msg like '%somestring%'

我知道这是一个不现实的查询,我只是想显示各种选项。

以下面的内容结束,它可以工作,所以我认为把它留在这里给其他人可能会很好。我使用for循环来检查并查看数组元素优先于正在处理的元素的字符是否包含布尔匹配之一,如果包含,则创建SQL语句。注意,循环中的第一个元素($i==0)用于搜索的第一个单词—在搜索字符串

的开头不应该有布尔形参。
// If the search string contains multiple boolean expressions, let's process them
// First add a space in case someone uses something like -searchword instead of - searchword
        $searchText = preg_replace('/(&|'||-|!)('S+)/imx', '$1 $2', $searchText);
        $keywords = explode(' ',mysql_real_escape_string($searchText));
        for($i=0; $i<count($keywords); $i++) {
            if ($i == 0) {
                $where .= " AND msg LIKE '%" . $keywords[$i] . "%'";
            }
            if (preg_match("/!|-|[Nn][Oo][Tt]/", $keywords[$i-1])) {
                $where .= " AND msg NOT LIKE '%" . $keywords[$i] . "%'";
            }
            if (preg_match("/&|[Aa][Nn][Dd]/", $keywords[$i-1])) {
                $where .= " AND msg LIKE '%" . $keywords[$i] . "%'";
            }
            if (preg_match("/'||[Oo][Rr]/", $keywords[$i-1])) {
                $where .= " OR msg LIKE '%" . $keywords[$i] . "%'";
            }
        }

你的解决方案是伟大的,但搜索"搜索某件事和另一件事"只会搜索搜索和另一个。对于短语,我添加了

$newKeyWords = array();
            $string = '';
            $counter = 1;
            foreach( $keywords as $keyName){
                if( $keyName !== 'AND' && $keyName !== 'OR' && $keyName !== 'NOT'){
                    $string .= ' '.$keyName;
                    if( $counter == count($keywords) ){
                        $newKeyWords[] = trim($string);
                    }
                }else{
                    $newKeyWords[] = trim($string);
                    $newKeyWords[] = $keyName;
                    $string = '';
                }
                $counter++;
            }

所以$keywords现在将是$newKeyWords,你也可以搜索短语。希望能有所帮助。