构造正则捕获预定义逗号分隔词,Groovy解析配置字符串遇阻
解决Groovy正则提取逗号分隔列表内容的问题
嘿,我懂你这会儿的困扰——写Groovy脚本解析配置字符串,本来没逗号列表的时候正则好好的,一加逗号分隔的列表,明明能匹配上,就是抓不到列表里的每个内容对吧?结合GitHub Hooks和Jenkins脚本的场景,这种配置解析需求太常见了,咱们来一步步搞定它。
问题根源
你之前的正则大概率是用了重复的捕获组(比如(\w+)(?:,(\w+))*),但Groovy(底层基于Java正则)有个特点:重复的捕获组只会保留最后一次匹配的内容,所以你只能拿到列表的最后一个元素,前面的都丢了。
解决方案:先抓整段,再拆分成单个词汇
正确的思路是先匹配包含整个逗号列表的片段,再把这段字符串拆分成单个词汇。下面分两种常见场景给你代码示例:
场景1:配置是键值对格式(比如key=val1,val2)
假设你的配置字符串长这样:
def configStr = "repo=my-github-repo, branches=main,develop,hotfix, env=production"
用这个正则+处理逻辑就能提取所有词汇:
// 正则匹配键值对,捕获键和完整的逗号分隔值串 def configPattern = /(\w+)(?:=((?:\w+)(?:,\s*\w+)*))?/ def matcher = configStr =~ configPattern matcher.each { matchResult -> def key = matchResult[1] def valueSegment = matchResult[2] if (valueSegment) { // 把逗号分隔的字符串拆成单个词汇(忽略逗号后的空格) def values = valueSegment.split(/,\s*/) values.each { word -> println "捕获到词汇:$word(来自键 $key)" } } else { // 处理没有值的情况(比如单纯的词汇项) println "捕获到词汇:$key" } }
场景2:配置是纯逗号分隔的词汇列表(比如foo, bar, baz)
这种情况更简单,直接用findAll提取所有符合规则的词汇就行:
def configStr = "feature-login, bugfix-payment, docs-update" def allWords = configStr.findAll(/\w+/) allWords.each { word -> println "捕获到词汇:$word" }
正则说明
- 对于键值对的正则
(\w+)(?:=((?:\w+)(?:,\s*\w+)*))?:(\w+):捕获键名(或者单纯的独立词汇)(?:=...):非捕获组,匹配=符号,不捕获这个符号本身((?:\w+)(?:,\s*\w+)*):捕获完整的逗号分隔值串,其中(?:,\s*\w+)*匹配0或多个“逗号+可选空格+词汇”的组合
- 拆分列表时用
split(/,\s*/):既能处理val1,val2,也能处理val1, val2这种带空格的情况
这样处理后,不管是单个词汇还是逗号分隔的列表,所有内容都能被准确提取出来,完美适配你结合GitHub Hooks和Jenkins脚本的需求。
内容的提问来源于stack exchange,提问作者Wesley Bland
相关产品推荐
相关产品推荐

