javascript - 如何解析使用波兰符号结构的搜索查询?
问题描述
我的应用程序有一个搜索框,它支持具有以下结构的查询:
输入: 具有以下结构的字符串:
<operand><phrase><category> <operand><phrase><category> ...
<operand>: can be + or - to denote include or exclude and is optional
<phrase>: can be a single word or a word or sentence surrounded by quotes
<category>: is surrounded by square brackets and can be either [c1], [c2], or [c3]
一个查询的示例:
+car "tart berries"[fruit] -"broccoli"[vegetable] "green onion"[vegetable] pepper[vegetable] -"my keys"[object]
期望的输出:
[
["+", "car", ""],
["" , "tart berries","fruit"],
["-", "broccoli"., "vegetable"],
["" , "green onion", "vegetable"],
["" , "pepper", "vegetable"]
]
我的代码:
我使用以下正则表达式来捕获组:
let re = /([+-]?)(\w+|".+?")(\[fruit\]|\[vegetable\]|\[object\])?/gi
var str = '+car "tart berries"[fruit] -"broccoli"[vegetable] "green onion"[vegetable] pepper[vegetable] -"my keys"[object]'
for (const match of str.matchAll(re)) {
console.log(match);
}
问题:
- 项目多次重复:
["+car", "+", "car"]
[""tart berries"[fruit]", "", ""tart berries"", "[fruit]"]
- 有没有办法从结果中排除引号。
"tart berries" instead of ""tart berries""
解决方案
您无法摆脱正则表达式中的引号,JS 正则表达式不支持分支重置组,因此您必须对匹配项进行后处理。
此外,要仅捕获不带方括号的c1
//值c2
,c3
您需要替换(\[a]|\[b]|\[c])?
为可选的非捕获组并将替代项重新分组为(?:\[(a|b|c)])
.
请注意,"[^"]*"
它比 更有效".+?"
。
您可以使用
let re = /([+-]?)(\w+|"[^"]*")(?:\[(fruit|vegetable|object)])?/gi
const rx_quotes = /^"|"$/g;
var str = '+car "tart berries"[fruit] -"broccoli"[vegetable] "green onion"[vegetable] pepper[vegetable] -"my keys"[object]'
let result = [];
for (const match of str.matchAll(re)) {
let [_,x,y,z] = match;
y = y.replace(rx_quotes,'');
if (z === undefined) z = "";
result.push([x,y,z]);
}
console.log(result);
正则表达式详细信息
([+-]?)
- 第 1 组:可选+
或-
字符(\w+|"[^"]*")
- 第 2 组:一个或多个单词字符或双引号之间的字符串(?:\[(fruit|vegetable|object)])?
- 一个可选的非捕获组匹配 1 或 0 次出现\[
- 一个[
字符(fruit|vegetable|object)
- 第 3 组:任何子串备选方案]
- 一个]
字符。
推荐阅读
- git - 想要 git checkout 标签,但没有文件?
- python - 在数据帧上执行 for 循环的更快替代方案?
- ubuntu-18.04 - GRUB2 如何找到 erubenv 文件的位置
- angular - AWS Cognito Amplify 身份验证和 Angular UI 组件
- javascript - Webpack:如何解析驻留在 js 文件中的 html 模板?
- ms-word - 如何确定内容控件在 Word 文档中的位置
- javascript - POST 请求 Express JS 和强大的内部错误 500
- javascript - 每秒运行一次抛出:MongoError:拓扑已破坏
- python - 类型错误:
() 在使用 apply 后跟 groupby 时得到了一个意外的关键字参数“axis” - excel-formula - 如果函数 - 多个条件