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

时间:2014-03-28 22:47:45

标签: php

给出字符串:

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

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

我已经尝试过preg_match,preg_match_all,preg_split和explode,但我似乎无法将其删除。

类似的东西:

    $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%'

我意识到这是一个不切实际的查询,我只想展示各种选项。

2 个答案:

答案 0 :(得分:0)

结束以下,这是有效的,所以我认为把它留给其他人可能会很好。 我使用for循环检查并查看数组元素 previous 中的字符是否包含一个布尔匹配,如果是,则创建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] . "%'";
            }
        }

答案 1 :(得分:0)

您的解决方案很棒,但搜索“搜索内容和其他内容”只会搜索搜索和其他内容。对于我添加的短语

$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++;
            }

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