You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bash正则、sed、grep或Groovy提取GitHub合并提交的首个Jira ID

从GitHub Squash合并提交消息中提取首个Jira ID

需求

从GitHub PR squash合并后的提交消息字符串中提取首个符合格式的Jira ID,Jira ID定义为「大写字母组-数字序列」(如ABCD-1234),需排除以下无效场景:

  • 前面紧跟其他大写字母组+横杠的(如FAKE-XYZ-575中的XYZ-575无效)
  • 前面是小写字母的(如abcdXYZ-576中的XYZ-576无效)

测试用例

ABCD-1231 dummy title XYZ-566 (#423)
=> ABCD-1231

[ABCD-1232, XYZ-566] dummy title (#424)
=> ABCD-1232

[ABCD-1233] dummy title (#425)
=> ABCD-1233

ABCD-1234: dummy title (#426)
=> ABCD-1234

XYZ-567 dummy title (#427)
=> XYZ-567

(XYZ-568) dummy title (#428)
=> XYZ-568

"XYZ-569" dummy title (#429)
=> XYZ-569

dummy title XYZ-570 dummy title (#430)
=> XYZ-570

DUMMY title XYZ-571 dummy title (#431)
=> XYZ-571

'feature/XYZ-572' dummy title (#432)
=> XYZ-572

FEATURE|XYZ-573 dummy title (#433)
=> XYZ-573

<Feature\XYZ-574> dummy title (#434)
=> XYZ-574

dummy title FAKE-XYZ-575 dummy title (#435)
=> <nothing>

dummy title abcdXYZ-576 dummy title (#436)
=> <nothing>

现有问题

Bash原生正则不支持负向零宽断言,导致之前的正则无法适配FEATURE|XYZ-573、[Feature\XYZ-574]等带特殊分隔符的场景,同时无法排除无效的Jira ID格式。

解决方案

1. 使用grep -P(推荐,支持Perl正则)

利用Perl正则的负向后行断言,精准匹配符合要求的Jira ID,并取第一个匹配结果:

commit_msg="FEATURE|XYZ-573 dummy title (#433)"
echo "$commit_msg" | grep -oP '(?<!([A-Z]+)-?)\b[A-Z]+-[0-9]+\b' | head -n 1

正则说明:

  • (?<!([A-Z]+)-?):负向后行断言,确保匹配的Jira ID前面不是「大写字母组+可选横杠」,排除FAKE-XYZ-575这类无效场景
  • \b:单词边界,确保Jira ID前后是非字母数字分隔符(如空格、括号、斜杠、竖线等)
  • [A-Z]+-[0-9]+:匹配标准Jira ID格式
  • head -n 1:只保留第一个匹配结果

2. 使用sed(兼容无grep -P的环境)

通过非贪婪匹配和捕获组实现,无需依赖Perl正则:

commit_msg="<Feature\XYZ-574> dummy title (#434)"
echo "$commit_msg" | sed -E 's/^.*?([^A-Z0-9]|^)([A-Z]+-[0-9]+)([^A-Z0-9]|$).*/\2/;t;d'

脚本说明:

  • ^.*?([^A-Z0-9]|^):非贪婪匹配开头到第一个「非字母数字字符或字符串开头」的位置
  • ([A-Z]+-[0-9]+):捕获符合格式的Jira ID
  • ([^A-Z0-9]|$):匹配Jira ID后的「非字母数字字符或字符串结尾」
  • t;d:如果替换成功则输出结果,否则输出空行

3. 使用Groovy脚本

若允许使用Groovy,可直接利用其支持的高级正则特性:

// extract_jira_id.groovy
def commitMsg = args[0]
def jiraPattern = ~/(?<!([A-Z]+)-?)\b[A-Z]+-[0-9]+\b/
def matcher = commitMsg =~ jiraPattern
println matcher.find() ? matcher.group() : ""

运行方式:

groovy extract_jira_id.groovy "'feature/XYZ-572' dummy title (#432)"

内容的提问来源于stack exchange,提问作者P. Luo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 16:34:51