拓冰建站拓冰建站
首页 / 资讯中心 / 正文

如何用 jq 的 @uri 过滤器对 JSON 字段做百分号编码以构建 URL 查询串

如何用 jq 的 uri 过滤器对 JSON 字段做百分号编码以构建 URL 查询串【免费下载链接】jqCommand-line JSON processor项目地址: https://gitcode.com/GitHub_Trending/jq/jq手头有一份 JSON 数据比如一个搜索词字段需要把它放进 URL 查询串里但字段值里包含空格、问号、引号等非 ASCII 或多字节字符直接拼接会破坏 URL 结构。jq 的uri过滤器可以完成这件事它对输入做百分号编码percent-encoding把保留的 URI 字符映射为%XX序列。以下内容基于 jq 官方手册v1.8与仓库中的测试用例所有命令都可以直接执行并用文档给出的输出核对结果。前提与调用方式按 jq 1.8 手册 的 SYNOPSIS 一节jq 的调用形式是jq [options...] filter [files...]不带文件名时jq 默认从stdin读取 JSON 流。因此下面的示例都用echo把 JSON 文档喂给 stdin也可以替换成你自己的 JSON 文件。uri 的两种用法手册在 “Format strings and escaping” 一节说明foo语法用于格式化与转义字符串“useful for building URLs”适合构建 URL其中uriApplies percent-encoding, by mapping all reserved URI characters to a%XXsequence。uriduri的逆操作做百分号解码。它有两种用法区别决定了哪些内容会被编码作为独立过滤器对整个输入值做编码例如.search | uri。后接字符串字面量uri ...。手册明确说明字符串字面量的内容不会被转义但字面量内的字符串插值\(exp)会被转义。第二种用法正是构建 URL 的关键URL 骨架https://、/、?、、写在字面量里保持原样只有 JSON 字段的值经过编码。主路径从 JSON 字段构建查询串手册给出了一个完整示例对输入{search:what is jq?}执行echo {search:what is jq?} | jq uri https://www.google.com/search?q\(.search)文档给出的输出是注意默认输出是带引号的 JSON 字符串https://www.google.com/search?qwhat%20is%20jq%3F可以看到字段值里的空格被编码为%20问号被编码为%3F而 URL 里的斜杠、?、因为属于字符串字面量部分未被改动。手册原文特意指出这一点“the slashes, question mark, etc. in the URL are not escaped, as they were part of the string literal”。如果希望输出裸字符串不带 JSON 引号以便直接交给非 JSON 系统使用加-r--raw-output选项。手册说明该选项下若过滤结果为字符串会直接写入标准输出而不是按 JSON 字符串加引号输出echo {search:what is jq?} | jq -r uri https://www.google.com/search?q\(.search)输出为不带引号的https://www.google.com/search?qwhat%20is%20jq%3F。多个查询参数因为uri可以作为独立过滤器使用且字面量内容不转义、插值内容转义所以多个参数可以在一条命令里拼出来。下面的示例仍复用手册示例中的输入值page1属于字面量部分不会被动两个插值部分各自按手册示例中的规则被编码echo {search:what is jq?} | jq -r uri https://www.google.com/search?q\(.search)page1预期输出为示例结果由文档示例推导组合而成非文档原文https://www.google.com/search?qwhat%20is%20jq%3Fpage1哪些字符会被编码来自测试用例的事实仓库中的 tests/uri.test 是 jq 官方的测试文件格式为三行一组程序、输入、期望输出。它给出的uri用例可以当作字符映射的权威依据以下均为文档示例输出输入期望输出\b\t\n\f\r\\\%08%09%0A%0C%0D%22%5C,-./09:;?AZ[\\]^_az{|}~\u007f|%2C-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7Fa μ ∰ a%20%CE%BC%20%E2%88%B0%20%F0%9F%98%8Ea\u0000b\u0000ca%00b%00c可以核对两点结论均直接来自上表不是经验推断第二行输入中-、.、/和字母数字在输出中原样保留其余符号,:?[]等全部变为%XX非 ASCII 字符按 UTF-8 多字节序列逐字节编码如μ变为%CE%BC变为%F0%9F%98%8ENUL 字符编码为%00。对照上一节的主路径示例what is jq?中的空格变%20、?变%3F与表中规则一致。验证用 urid 做往返检查urid是uri的逆操作。同样的测试文件给出了往返对文档示例echo %2C-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F | jq urid期望输出还原为原字符串,-./09:;?AZ[\\]^_az{|}~\u007f对上一节uri的编码结果执行urid若能还原出原始字段值说明编码与解码两侧一致。urid还会对不合法的百分号编码报错。测试文件记录了这些现象文档示例echo abc% | jq . | try urid catch .输出string (\abc%\) is not a valid uri encoding同样的错误信息也出现在%后只有一个十六进制数字abc%f、%后跟非十六进制字符abc%g、非法十六进制值%FX%9F%98%8E、不完整的 4 字节 UTF-8 序列%F0%93%81等情况。如果你解码外部来源的 URL 片段遇到这类报错应视为输入数据问题而不是 jq 的故障。边界与限制uri会编码除字母数字和-、.、/以外的所有字符见上表测试用例。如果你构建的是查询参数值/、?、、都会被编码成%2F、%3F、%26、%3D——这正是查询参数想要的行为但如果你想保留 URL 结构本身就必须用uri 字面量\(插值)形式而不能对整条 URL 执行裸uri。手册未对uri的输出声明任何特定 RFC 编号或兼容性范围编码规则以foo一节的描述和 tests/uri.test 的用例为准。需要输出裸字符串去掉 JSON 引号时记得加-r否则下游拿到的是带引号的 JSON 文本。参考资料docs/content/manual/manual.ymljq 1.8 手册“Format strings and escaping”、“String interpolation:\(...)” 与--raw-output/-r选项说明。tests/uri.testuri/urid的官方测试用例含期望输出与报错信息。【免费下载链接】jqCommand-line JSON processor项目地址: https://gitcode.com/GitHub_Trending/jq/jq创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门