拆分关键字查询 (SELECT/FROM/WHERE/AND/OR)
Splitting query on key words (SELECT/FROM/WHERE/AND/OR)
嘿,下面是我一直在处理的以下代码:
var sql = "SELECT pillers, Balloons, Tacks FROM the_database_file WHERE Balloons != 'small' AND Balloons != 'large' AND Blah = 'bobby';";
$(document).ready(function() {
var findFROM = sql.indexOf(" FROM");
var findWHERE = sql.indexOf(" WHERE");
var findAND = sql.indexOf(" AND");
var findOR = sql.indexOf(" OR");
var findSemicolon = sql.indexOf(";");
var findCountAND = sql.match(/\AND\b/g);
var findCountOR = sql.match(/\OR\b/g);
var txtSELECT = sql.substring(0, findFROM);
var txtFROM = sql.substring(findFROM, findWHERE);
var txtWHERE = "";
var txtAND = "";
var txtOR = "";
if (findAND != -1) {
var _tmpPos = 0;
var _tmpAND = "";
findCountAND = (findCountAND? findCountAND.length : 0);
findCountOR = (findCountOR? findCountOR.length : 0);
for (var i = 1; i < findCountAND; i++) {
console.log(i);
_tmpPos = nth_occurrence(sql, ' AND', i);
_tmpPos = findAND;
findAND = sql.indexOf(" AND");
_tmpAND = sql.substring(_tmpPos, findAND);
}
txtWHERE = sql.substring(findWHERE, findAND);
}
$('#SELECT').text(txtSELECT);
$('#FROM').text(txtFROM);
$('#WHERE').text(txtWHERE);
$('#test').text(findAND);
});
function nth_occurrence(string, char, nth) {
var first_index = string.indexOf(char);
var length_up_to_first_index = first_index + 1;
if (nth == 1) {
return first_index;
} else {
var string_after_first_occurrence = string.slice(length_up_to_first_index);
var next_occurrence = nth_occurrence(string_after_first_occurrence, char, nth - 1);
if (next_occurrence === -1) {
return -1;
} else {
return length_up_to_first_index + next_occurrence;
}
}
}
我正在尝试这样格式化它:
SELECT pillers, Balloons, Tacks
FROM the_database_file
WHERE Balloons != 'small'
AND Balloons != 'large'
AND Blah = 'bobby';
但是,我被困在试图在查询字符串中找到多个 AND 或 OR 的领域。上面的示例只有 2 个 AND 开始,但我似乎无法获得正确的代码。
找到 nth_occurrence 函数 HERE。
如果有人能帮助我,那就太好了。可能只需要一个正则表达式?谁知道?
一个JSFIDDLE也已经设置好了。
更新
感谢好心的论坛成员 HERE I was able to update my JSFIDDLE 我试图重现他所做的事情:
[ { word: 'SELECT', index: 0, text: 'pillers, Balloons, Tacks' },
{ word: 'FROM', index: 32, text: 'the_database_file' },
{ word: 'WHERE', index: 55, text: 'Balloons != \'small\'' },
{ word: 'AND', index: 81, text: 'Balloons != \'large\'' },
{ word: 'AND', index: 105, text: 'Blah = \'bobby\'' },
{ word: ';', index: 123 } ]
然而,我的尝试并没有得到同样的结果。有帮助吗?
你的实现真的很棘手,我能想象到很多情况,当它解析失败时。
我建议不要重新发明轮子,而是使用现有的库来解析 SQL 和 JS:
和其他人。有很多不同复杂性的现成解决方案。
找到解决方案:
function parseSql(sql) {
var found = [];
["SELECT", "WHERE", "FROM", "AND", "OR", ";"].forEach(function(word) {
var idx = sql.indexOf(word);
while(idx!==-1) {
found.push({word:word, index:idx});
idx = sql.indexOf(word, idx + 1);
keptIdx = idx;
}
});
found.sort(function(x,y) { return x.index - y.index });
found.forEach(function(x, i, xs) {
if (i < xs.length - 1) {
x.text = sql.substring(x.index, xs[i + 1].index).replace(xs[i].word, "").trim();
}
});
return found;
}
嘿,下面是我一直在处理的以下代码:
var sql = "SELECT pillers, Balloons, Tacks FROM the_database_file WHERE Balloons != 'small' AND Balloons != 'large' AND Blah = 'bobby';";
$(document).ready(function() {
var findFROM = sql.indexOf(" FROM");
var findWHERE = sql.indexOf(" WHERE");
var findAND = sql.indexOf(" AND");
var findOR = sql.indexOf(" OR");
var findSemicolon = sql.indexOf(";");
var findCountAND = sql.match(/\AND\b/g);
var findCountOR = sql.match(/\OR\b/g);
var txtSELECT = sql.substring(0, findFROM);
var txtFROM = sql.substring(findFROM, findWHERE);
var txtWHERE = "";
var txtAND = "";
var txtOR = "";
if (findAND != -1) {
var _tmpPos = 0;
var _tmpAND = "";
findCountAND = (findCountAND? findCountAND.length : 0);
findCountOR = (findCountOR? findCountOR.length : 0);
for (var i = 1; i < findCountAND; i++) {
console.log(i);
_tmpPos = nth_occurrence(sql, ' AND', i);
_tmpPos = findAND;
findAND = sql.indexOf(" AND");
_tmpAND = sql.substring(_tmpPos, findAND);
}
txtWHERE = sql.substring(findWHERE, findAND);
}
$('#SELECT').text(txtSELECT);
$('#FROM').text(txtFROM);
$('#WHERE').text(txtWHERE);
$('#test').text(findAND);
});
function nth_occurrence(string, char, nth) {
var first_index = string.indexOf(char);
var length_up_to_first_index = first_index + 1;
if (nth == 1) {
return first_index;
} else {
var string_after_first_occurrence = string.slice(length_up_to_first_index);
var next_occurrence = nth_occurrence(string_after_first_occurrence, char, nth - 1);
if (next_occurrence === -1) {
return -1;
} else {
return length_up_to_first_index + next_occurrence;
}
}
}
我正在尝试这样格式化它:
SELECT pillers, Balloons, Tacks
FROM the_database_file
WHERE Balloons != 'small'
AND Balloons != 'large'
AND Blah = 'bobby';
但是,我被困在试图在查询字符串中找到多个 AND 或 OR 的领域。上面的示例只有 2 个 AND 开始,但我似乎无法获得正确的代码。
找到 nth_occurrence 函数 HERE。
如果有人能帮助我,那就太好了。可能只需要一个正则表达式?谁知道?
一个JSFIDDLE也已经设置好了。
更新
感谢好心的论坛成员 HERE I was able to update my JSFIDDLE 我试图重现他所做的事情:
[ { word: 'SELECT', index: 0, text: 'pillers, Balloons, Tacks' },
{ word: 'FROM', index: 32, text: 'the_database_file' },
{ word: 'WHERE', index: 55, text: 'Balloons != \'small\'' },
{ word: 'AND', index: 81, text: 'Balloons != \'large\'' },
{ word: 'AND', index: 105, text: 'Blah = \'bobby\'' },
{ word: ';', index: 123 } ]
然而,我的尝试并没有得到同样的结果。有帮助吗?
你的实现真的很棘手,我能想象到很多情况,当它解析失败时。
我建议不要重新发明轮子,而是使用现有的库来解析 SQL 和 JS:
和其他人。有很多不同复杂性的现成解决方案。
找到解决方案:
function parseSql(sql) {
var found = [];
["SELECT", "WHERE", "FROM", "AND", "OR", ";"].forEach(function(word) {
var idx = sql.indexOf(word);
while(idx!==-1) {
found.push({word:word, index:idx});
idx = sql.indexOf(word, idx + 1);
keptIdx = idx;
}
});
found.sort(function(x,y) { return x.index - y.index });
found.forEach(function(x, i, xs) {
if (i < xs.length - 1) {
x.text = sql.substring(x.index, xs[i + 1].index).replace(xs[i].word, "").trim();
}
});
return found;
}