问题引入
我在个人项目 typora_plugin 里,设计了一个简单的查询语法(其实是抄袭 Google 的查询语法),用于精确的搜索 md 文件。
我个人认为是比较符合直觉的。但是很多用户反馈【看不懂】、【用不懂】。
我的问题是:
- 以下两个表格是我对于搜索语法的解释,你愿意看吗?觉得自己能轻松使用它吗?
- 你是否理解以下的解释?初看时有什么疑问吗?觉得还需要补充什么?
- 针对 md 文件的搜索功能,你觉得以下搜索语法还能怎么优化?
语法关键字说明
| 关键字 | 说明 |
|---|---|
| whitespace | 表示与。文档应该同时包含全部关键词,等价于 AND |
| | | 表示或。文档应该包含关键词之一,等价于 OR |
| - | 表示非。文档不能包含关键词 |
| “” | 表示词组。双引号里的空格不再视为与,而是词组的一部分 |
| /RegExp/ | JavaScript 风格的正则表达式 |
| scope | 查询属性,用于限定搜索条件 1. 文件属性:path | file | ext | time | size | linenum | charnum | crlf | hasimage 2. 内容属性:default | content | frontmatter | line | blockcode | blockcodelang | blockcodebody | blockhtml | blockquote | table | thead | tbody | ol | ul | head | image | code | link | strong | em | del 3. 默认值 default = path + content(路径+文件内容) |
| operator | 操作符。 1. 「:」表示文本包含或正则匹配(默认) 2. 「=」「!=」表示文本、数值、布尔的严格相等/不相等 3. 「>」「<」「>=」「<=」表示数值比较 |
| () | 小括号。用于调整运算顺序 |
语法示例
| 示例 | 搜索文档 |
|---|---|
| pear | 包含 pear。等价于 default:pear |
| sour pear | 包含 sour 和 pear。等价于 sour AND pear |
| sour | pear | 包含 sour 或 pear。等价于 sour OR pear |
| “sour pear” | 包含 sour pear 这一词组 |
| sour pear -apple | 包含 sour 和 pear,且不含 apple |
| /\bsour\b/ pear time=2024-03-12 | 匹配正则\bsour\b(全字匹配sour),且包含 pear,且文件更新时间为 2024-03-12 |
| frontmatter:开发 | head=plugin | strong:MIT | YAML Front Matter 包含开发 或者 标题内容为 plugin 或者 加粗文字包含 MIT |
| size>10k (file=k8s.md | hasimage=true) | 文件大小大于 10k,且 文件名为 k8s.md 或者文件内容包含图片 |
| path:(info | warn | err) -ext:md | 文件路径包含 info 或 warn 或 err,且扩展名不含 md |
| file:/[a-z]{3}/ content:prometheus blockcode:“kubectl apply” | 文件名匹配正则 [a-z]{3},且内容包含 prometheus,且代码块内容含有 kubectl apply |
BNF grammar
<query> ::= <expression>
<expression> ::= <term> ( <or> <term> )*
<term> ::= <factor> ( <conjunction> <factor> )*
<factor> ::= <qualifier>? <match>
<qualifier> ::= <scope> <operator>
<match> ::= <keyword> | '"'<keyword>'"' | '/'<regexp>'/' | '('<expression>')'
<conjunction> ::= <and> | <not>
<and> ::= 'AND' | ' '
<or> ::= 'OR' | '|'
<not> ::= '-'
<keyword> ::= [^\s"()|]+
<regexp> ::= [^/]+
<operator> ::= ':' | '=' | '!=' | '>=' | '<=' | '>' | '<'
<scope> ::= 'path' | 'file' | 'ext' | 'time' | 'size' | 'linenum' | 'charnum' | 'crlf' | 'hasimage' | 'default' | 'content' | 'frontmatter' | 'line' | 'blockcode' | 'blockcodelang' | 'blockcodebody' | 'blockhtml' | 'blockquote' | 'table' | 'thead' | 'tbody' | 'ol' | 'ul' | 'head' | 'image' | 'code' | 'link' | 'strong' | 'em' | 'del'
