JQ如何编写多条件正则提取两种格式的容器镜像名称
兼容两种镜像格式提取镜像名的实现方法
问题场景
当前镜像字段存在两种取值格式:
- 标签格式:
docker/nginx:latest - 摘要格式:
docker/nginx@sha256:9560f8528a3cd
原有表达式仅能提取冒号分隔格式下,仓库路径与标签之间的镜像名:
.image | match("(?<=\\/)(.*)(?=\\:)").captures[].string
尝试添加@匹配的写法失效,失效写法如下:
.image | match("(?<=\\/)(.*)(?=\\: | \\@)").captures[].string
待处理的两类JSON样例:
// 标签格式 { "image": "docker/nginx:latest" } // 摘要格式 { "image": "docker/nginx@sha256:9560f8528a3cd" }
失效原因
失效写法的正则前瞻部分(?=\\: | \\@)里加了多余的空格,正则会严格匹配冒号、@符号前的空格,但实际镜像字符串里两个分隔符前后都没有空格,因此匹配失败。另外正则里的冒号、斜杠都不属于必须转义的特殊字符,多余转义只会增加写法复杂度。
可用方案
方案1:修正正则写法
把前瞻部分的多余空格删除,用字符组匹配冒号、@两种分隔符即可,修正后的表达式:
.image | match("(?<=/)(.*)(?=[:@])").captures[].string
两个样例执行后都能正确返回nginx。
方案2:用分割函数绕开正则(更稳定)
如果担心正则写作出错,或者后续要兼容多级仓库路径(比如docker.io/library/nginx:1.25),可以直接用jq内置的split函数处理,不需要写正则,容错性更高:
.image | split("/")[-1] | split("[:@]")[0]
处理逻辑:
- 先按
/分割字符串,取最后一段,剔除前面的仓库地址/命名空间部分 - 再按
:或者@分割上一步的结果,取第一段,就是最终的镜像名
内容的提问来源于stack exchange,提问作者eramm
相关产品推荐
相关产品推荐

