Groovy场景下如何提取所有方括号内的工单标识生成可遍历列表
实现方案说明
命令行grep类实现(轻量文本过滤场景)
- GNU grep 方案(Linux环境默认支持):执行
grep -Po '(?<=\[)[^\]]+(?=\])' 目标文本文件即可,-o参数表示仅输出匹配到的内容,-P参数开启Perl兼容正则支持。匹配规则依靠零宽断言实现,不会匹配无方括号包裹的纯文本内容 - 跨平台兼容方案(支持macOS、WSL环境):如果系统默认grep不支持
-P参数,可使用Perl一行命令替代:perl -ne 'print "$1\n" while /\[([^\]]+)\]/g' 目标文本文件,逻辑和上述grep完全一致,逐行提取方括号内的内容输出 - 执行后输出效果完全匹配目标格式,所有方括号内的内容逐行输出,无方括号的纯文本不会被匹配输出
Groovy环境全量提取实现
原实现存在的逻辑偏差:
- 将字符串集合的Matcher对象和文件读取的
readLines()方法混用,属于不同类的方法拼接,逻辑不通- 未遍历Matcher的匹配结果,单次取
[0]仅能拿到全局第一个匹配项,无法收集单条文本内出现的多个工单(比如示例里同一条文本带两个DPDHLPA工单的场景)- 纯文本行因无方括号匹配本应被自然过滤,但原写法因逻辑错位根本无法走到过滤步骤
之前尝试用collectMany未达预期,基本是因为在每行的处理逻辑里,没有循环调用matcher.find()遍历所有匹配位置,仅取了第一个匹配结果就返回,最终收集到的列表不全。
可直接运行的正确实现:
def changeString = [ '[DPDHLPA-26607] Updating robots.txt', '[DPDHLPA-2321] [DPDHLPA-2322] Updating something.txt', 'asdfasdf' // 无方括号的纯文本会被自动跳过 ] def ticketPattern = ~/\[([^\]]+)\]/ def TICKET_LIST = changeString.collectMany { line -> def lineTickets = [] def matcher = line =~ ticketPattern // 循环遍历当前行的所有匹配项,直到没有可匹配内容为止 while (matcher.find()) { lineTickets << matcher.group(1) } lineTickets }.unique().sort() // 输出结果:[DPDHLPA-26607, DPDHLPA-2321, DPDHLPA-2322] println TICKET_LIST
实现逻辑说明:
- 用
collectMany将每行的提取结果拍平成统一列表,刚好解决同一条文本内多个工单的收集问题 - 用
matcher.find()循环遍历所有匹配位置,不会只停留在第一个匹配项上 - 纯文本行因为匹配不到规则返回空列表,自然被过滤不进入结果集
- 最后通过
unique()去重、sort()排序,得到的列表可以直接用来循环拼接工单URL,不需要额外处理
如果需要输出成换行分隔的纯文本格式,只需要在最后追加.join('\n')即可,和最初的目标格式完全一致。
内容的提问来源于stack exchange,提问作者WhoAmI
相关产品推荐
相关产品推荐

