ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

jsongrep查询语法完整清单:10个正则路径运算符让你精通JSON搜索

jsongrep查询语法完整清单:10个正则路径运算符让你精通JSON搜索

【免费下载链接】jsongrep

A path query language for JSON, YAML, TOML, and other serialization formats.

项目地址:https://gitcode.com/gh_mirrors/js/jsongrep
点击查看免费下载

jsongrep 是一个用 Rust 编写的命令行工具和库,专门用于在 JSON、YAML、TOML 等文档中快速执行路径查询(path query)。它的查询语言复用了正则表达式的设计思路——把 JSON 文档看作一棵树,用"路径上的正则"描述你想匹配的位置。只需掌握下面 10 个核心运算符,你就能写出不限深度的复杂 JSON 搜索。

为什么 jsongrep 的查询像正则表达式?

JSON 文档本质上是一棵树:对象和数组层层嵌套,边由字段名或数组下标标记。jsongrep 让你用正则式运算符描述"路径集合",而不是像jq那样描述"如何转换数据":

**.name # 在任意深度的嵌套对象中找 "name" users[*].email # 匹配 users 数组里每个元素的 email (error|warn).* # error 或 warn 下的任意一层字段

查询会先编译为 NFA(非确定有限自动机),再确定化为 DFA(确定有限自动机)执行,因此搜索速度非常快。相关实现可以看 src/query/nfa.rs、src/query/dfa.rs 和 src/query/parser.rs。

10 个正则路径运算符完整清单

#运算符示例含义
1顺序拼接foo.bar.baz依次经过foo→bar→baz
2字段访问foo/"foo bar"匹配指定字段(含空格需加引号)
3数组下标[0]、[1]匹配数组中的特定位置
4数组切片[1:3]、[3:]、[:2]匹配一段下标(结束位置不包含)
5数组通配符[*]匹配数组的所有元素
6字段通配符*匹配任意一层字段名
7选择(并集)year \| category匹配多个字段之一
8可选foo?.barfoo可有可无
9重复(Kleene 星)foo*前一步重复零次或多次
10递归下降**匹配零层或多层任意字段

所有运算符都可以通过括号任意嵌套分组,比如foo.(bar|baz).qux匹配foo.bar.qux或foo.baz.qux。完整文法定义见 src/query/grammar/query.pest。

1. 顺序拼接:按路径逐层深入

最基础的写法,字段之间用.连接:

jg 'name.first' person.json # 输出 name.first: "John"

2. 字段访问:支持带空格的字段名

普通字段直接写名称;字段名含空格等保留字符时用双引号包裹:

jg '"first name".value' data.json

3. 数组下标:精确定位

下标从 0 开始,字段后可连续追加多个下标,如items[0][1]:

jg 'hobbies[1]' person.json # hobbies.[1]: # "yoga"

4. 数组切片:只取一段数据

写法与 Python 切片一致,结束下标不包含:

  • [1:3]:第 2 到第 4 个元素
  • [3:]:从第 4 个开始到末尾
  • [:2]:前 2 个元素

5. 数组通配符[*]:展开所有元素

这是最常用的运算符之一,取出数组中每个元素:

echo '{"users": [{"name": "Alice"}, {"name": "Bob"}]}' | jg 'users[*].name' # users.[0].name: # "Alice" # users.[1].name: # "Bob"

6. 字段通配符*:任意一层字段

注意*只匹配一层字段,不是递归搜索——这是它和**的关键区别:

jg 'dependencies.*.version' Cargo.toml # 列出所有依赖的版本号

7. 选择运算|:一次取多个字段

用|在一层内做"或",省掉多次查询:

jg 'prizes[0].(year|category)' prize.json # prizes.[0].year: # "2025" # prizes.[0].category: # "chemistry"

8. 可选运算?:字段可能不存在

foo?表示该步可有可无,适合处理字段可选的结构(如 TOML/YAML 配置):

jg 'database.port?.max_connections' config.yaml

9. 重复运算*:某一步重复任意次

后缀*让前一个"步骤"重复零次或多次,比如users*会匹配零个、一个或多个users层。

10. 递归下降**:任意深度搜索

**(即"字段通配符 + Kleene 星")是最强的运算符,匹配任意深度的路径:

jg '**.name' tree.json

如果想要在对象和数组中都递归,使用(* | [*])*:

jg '(* | [*])*.foo' data.json # 在任何深度找到所有名为 foo 的字段

💡 提示:不想手写**?CLI 的-F/--fixed-string参数会自动把查询当作字段名做任意深度搜索,例如jg -F firstname prize.json等价于**firstname的语义。

实战组合:写出复杂查询的三个技巧

  1. 括号改变优先级:(error|warn).message先分组再拼接;不加括号会被解析错。
  2. 多文件批量查询:同一个查询只编译一次,可依次作用于多个文件并自动识别格式(JSON/YAML/TOML/JSONL/CBOR/MessagePack):
    jg 'services.*.image' staging/docker-compose.yml prod/docker-compose.yml
  3. 配合输出参数:-r输出原始字符串(类似jq -r)、--count统计匹配数、-l只打印有匹配的文件名,方便管道处理。

完整测试数据可参考 tests/data/simple/simple.json。

性能如何:基准测试一图看懂

jsongrep 使用 Criterion 与 jsonpath-rust、jmespath、jaq、jql 四个主流查询库做了对比基准,测试数据从几 KB 的小样例到 190 MB 的 GeoJSON 文件。下图是 xlarge 规模的端到端(解析 + 编译 + 搜索)耗时小提琴图,jsongrep 各查询类型的分布明显更窄更靠左,意味着更快也更稳定:

基准方法论与源码见 benches/README.md 和 benches/query.rs。

快速上手与延伸阅读

🚀 安装与最小示例:

cargo install jsongrep # 或 brew install jsongrep echo '{"a": {"b": 1}}' | jg 'a.b'

想了解更多可以逛这些目录:

  • 查询引擎核心:src/query/(AST、解析、NFA/DFA)
  • 可运行的查询构建器示例:examples/query_builder.rs
  • 解析 + 查询完整流程示例:examples/parse_and_query.rs
  • 贡献指南:CONTRIBUTING.md

📌 最后一个小知识:文法中还保留了/regex/语法用于"按模式匹配字段名",但引擎尚未实现执行该语法,目前会报 "Unsupported feature" 错误——规划中,敬请期待。

【免费下载链接】jsongrep

A path query language for JSON, YAML, TOML, and other serialization formats.

项目地址:https://gitcode.com/gh_mirrors/js/jsongrep
点击查看免费下载

相关推荐

上一篇:React语法高亮神器react-syntax-highlighter:一站式解决代码展示难题
下一篇:终极指南:Weasis开源医学影像查看器的完整使用教程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表