如何检测未使用括号的歧义性无效布尔查询?
布尔查询歧义场景检测实现方案
核心思路
要检测这类歧义查询,核心原则是:在没有括号明确优先级的连续查询片段中,不能同时出现两种及以上不同的布尔运算符(AND/OR/NOT)。同一种运算符连续使用(如全AND、全OR、连续NOT)不会产生歧义,属于有效查询;一旦混合不同运算符且无括号包裹,就判定为无效并触发错误。
具体实现步骤
1. 词法分析(Tokenization)
先将原始查询字符串拆分为标准化的Token,包括:
- 操作数:查询关键词(如
love、family) - 运算符:统一转为大写的
AND/OR/NOT - 括号:
(和)
处理要点:
- 忽略多余空格,统一运算符大小写(避免
and/Or的差异) - 拆分带括号的Token(比如
(love拆为(+LOVE,peace)拆为PEACE+))
示例代码(Python):
def tokenize(query): tokens = [t.upper() for t in query.strip().split() if t.strip()] token_list = [] for token in tokens: if token.startswith('('): token_list.append('(') if len(token) > 1: token_list.append(token[1:]) elif token.endswith(')'): if len(token) > 1: token_list.append(token[:-1]) token_list.append(')') else: token_list.append(token) return token_list
2. 跟踪括号嵌套,隔离安全区域
遍历Token序列时,标记当前是否处于括号内部:
- 进入括号(遇到
()时,清空当前追踪的运算符集合,括号内的子查询无需检测(括号已明确优先级) - 退出括号(遇到
))时,同样清空运算符集合,后续重新追踪外部的运算符类型
3. 检测非括号区域的运算符混合
对于非括号包裹的连续片段,收集出现的运算符类型:
- 如果收集到的运算符类型数量≥2,直接判定为无效查询
- 全程维护当前片段的运算符集合,一旦发现混合立即返回结果
示例检测代码:
def is_invalid_query(query): tokens = tokenize(query) in_parentheses = 0 current_ops = set() for token in tokens: if token == '(': in_parentheses += 1 if len(current_ops) > 1: return True current_ops.clear() elif token == ')': in_parentheses -= 1 current_ops.clear() elif token in ('AND', 'OR', 'NOT'): if in_parentheses == 0: current_ops.add(token) if len(current_ops) > 1: return True # 检查最后一段非括号区域 return len(current_ops) > 1
4. 边界情况补充
- 处理括号不匹配:可以在词法分析后额外检查括号的数量是否相等,这类属于语法错误,也需触发提示
- 连续重复运算符:比如
love AND AND family,属于语法错误,可单独检测,但不属于歧义场景,按需处理
测试验证
将示例查询传入检测函数,结果符合预期:
- 有效查询返回
False,如love AND family AND trees、(love OR family) AND peace - 无效查询返回
True,如love AND family OR trees、(love OR family) AND peace OR ash
内容的提问来源于stack exchange,提问作者codingrohtak
相关产品推荐
相关产品推荐

