我有一种SQL查询,想按“ AND”和“ OR”进行拆分。问题在于这样的关键字可能在查询中以撇号或引号引起来。
例如。以下查询:
attribute1 IS 'test AND attribute2 IS NOT 'test' AND attribute2 IN ('me and you', 'me or you')
应该分为以下几类:
attribute1 IS 'test
attribute2 IS NOT 'test'
attribute2 IN ('me and you', "me or you")
因此,基本上不应该处理撇号或引号中的任何字符串(“ me and you”,“ me or you”)。
我如何用一个正则表达式来做到这一点?实际上是两个,一个用“ OR”分割,另一个用“ AND”分割。
在此先感谢您的帮助!
马吕斯
最佳答案
正如Wiktor所说的那样,编写您自己的解析器。尝试使用单个正则表达式执行此操作可能会导致难以阅读和维护代码。
然而,正则表达式可能有助于大大减少您自己的解析器编码。尝试使用此处描述的方法:http://www.rexegg.com/regex-best-trick.html(文章很长,您可能希望直接跳到“匹配Tarzan”,而不是“ Tarzan”部分)。
简而言之:使用此表达式:
'.*?'|".*?"|(AND|OR)
演示(查找绿色突出显示):https://regex101.com/r/jC2jC9/1。注意:演示中的表达式比
'.*?'|".*?"|(AND|OR)
稍微复杂一些,因为在后者中,我只是想更清晰地概述一下想法。然后,在Java代码中找到所有已定义
group(1)
的匹配项。引号中的“与”和“或”将被前两个替代方案覆盖,并且不会被该组捕获。现在,您需要使用已定义start()
的匹配项的end()
和group(1)
索引分割输入字符串:Pattern pattern = Pattern.compile("'.*?'|\".*?\"|\\s*\\b(AND|OR)\\b\\s*", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(input);
int nextPartPos = 0;
while (matcher.find()) {
if (matcher.group(1) != null) {
System.out.println(input.substring(nextPartPos, matcher.start()));
nextPartPos = matcher.end();
System.out.println("--> " + matcher.group(1) + " <--");
}
}
if (nextPartPos < input.length()) {
System.out.print(input.substring(nextPartPos));
}
完整的演示代码:https://ideone.com/3cmGhY
最后说明:当您看到需要层次结构来实现AND / OR优先级时,此代码实际上构建了子表达式的平面列表。我敢肯定,在代码中添加树构建功能并不重要。我并不是在这里只是为了专注于主要思想。
关于java - 如何用单词而不是撇号将字符串分开,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39016880/