在 PHP 中为布尔查询的每个项目添加一个术语(reg exp?)



在浏览器端,用户将输入一个布尔查询,这可能会变得复杂,我想将其转换为 SQL SELECT 语句。

用户将输入一个文本字符串,沿a AND ((b OR c) OR (not d))行。正如我所说,这是一个任意文本字符串,包含一个布尔表达式。

它是针对软件招聘人员的,所以a,b,c,d等将是技能,如C,C++,UML,Python等,以便前面的示例实际上可以读取C++ AND ((UML OR Python) OR (not Perl))

我想扩展到(在这种情况下(SELECT * FROM candidates WHERE skill=C++ AND ((skill=UML OR skill=Python) OR (not skill=Perl)).

我可以在语句前面加上SELECT,但是我如何将(例如(C++ AND ((UML OR Python) OR (not Perl))转换为 skill=C++ AND ((skill=UML OR skill=Python) OR (not skill=Perl)) 并在 PHP 中为任何带有任意数量括号的任意布尔表达式执行此操作?

我从您发布的示例中得出了以下观察结果: 您要做的就是将像C++这样的令牌替换为形式为 skill=C++ 的令牌,查询的其余部分保持不变。如果这并不总是正确的,您可能需要一个更复杂的解决方案,但如果这对您来说足够了,以下内容应该有效:

$expr = 'C++ AND ((UML OR Python) OR (not Perl))';
// remove tokens that will not be replaced, here `(`, `)`, and `not`
$trimmed = str_replace(['(', ')', 'not'], ['', '', ''], $expr);
// split string based on the keywords `AND` and `OR` (case insensitive)
// keywords will also not be replaced
$tokens = preg_split('/AND|OR/i', $trimmed);
// create replacement tokens without leading/trailing whitespace
$replacementTokens = [];
foreach ($tokens as &$token) {
    $token = trim($token);
    $replacementTokens[] = "skill=$token";
}
// replace tokens and construct the query
$where = str_replace($tokens, $replacementTokens, $expr);
$query = "SELECT * FROM candidates WHERE $where";

如前所述,如果您需要更复杂的行为,此解决方案可能不起作用。您可能还需要扩展关键字列表。但对于您提供的简单用例,它避免了实际解析查询的需要。

最后一点,请确保清理用户输入,这样您就不会受到SQL注入的影响。

最新更新