Groovy中嵌套正则表达式捕获内部分组的技术问题
保留多个精准正则时捕获分组目标值的解决方案
针对你需要保留三个精准正则、同时正确捕获分组目标值的需求,提供以下几种可行方案:
方案1:逐个匹配每个正则(最直观且精准)
直接遍历三个正则,对每个正则单独执行匹配操作,这样每个匹配的分组结果完全符合原正则的设计,不会出现合并后的分组混乱问题:
def patterns = [ ~/arg1:\s([\w\s\.\-\:]+)/, ~/arg2\s\-\s([\w\s\.\-\:]+)/, ~/arg3="([\w\s\.\-\:]+)"/ ] // 定义正则到转换方法的映射,替代繁琐的if-else判断 def transformMap = [ patterns[0]: this.&transformArg1, patterns[1]: this.&transformArg2, patterns[2]: this.&transformArg3 ] patterns.each { pattern -> (data.value =~ pattern).each { match -> def targetValue = match[1] def newValue = transformMap[pattern](targetValue) // 这里添加newValue的后续处理逻辑 } }
这种方式完全保留了每个正则的精准性,避免误匹配,分组取值逻辑清晰。
方案2:合并正则分支,统一处理分组
如果希望用单一正则完成匹配,可以将三个正则用分支|连接,每个分支保持原有精准格式,通过判断不同分组的非空值来获取目标数据:
def combinedPattern = ~/(?:arg1:\s([\w\s\.\-\:]+)|arg2\s\-\s([\w\s\.\-\:]+)|arg3="([\w\s\.\-\:]+)")/ (data.value =~ combinedPattern).each { match -> // 取第一个非空的捕获组值 def targetValue = match[1] ?: match[2] ?: match[3] def newValue = null // 根据非空分组判断参数类型,调用对应转换方法 if (match[1]) { newValue = transformArg1(targetValue) } else if (match[2]) { newValue = transformArg2(targetValue) } else if (match[3]) { newValue = transformArg3(targetValue) } // 后续处理逻辑 }
这里用(?:...)将每个分支标记为非捕获组,确保只有目标数据被捕获,同时保留了每个原正则的精准匹配规则,不会出现误匹配情况。
方案3:使用命名捕获组(Groovy特性)
Groovy支持命名捕获组,可以给每个分支的目标值设置相同的分组名称,直接通过名称取值,代码可读性更强:
def combinedPattern = ~/(?:arg1:\s(?<target>[\w\s\.\-\:]+)|arg2\s\-\s(?<target>[\w\s\.\-\:]+)|arg3="(?<target>[\w\s\.\-\:]+)")/ (data.value =~ combinedPattern).each { match -> def targetValue = match.group("target") def newValue = null // 根据匹配的前缀判断参数类型 def matchStr = match[0] if (matchStr.startsWith("arg1:")) { newValue = transformArg1(targetValue) } else if (matchStr.startsWith("arg2 -")) { newValue = transformArg2(targetValue) } else if (matchStr.startsWith("arg3="")) { newValue = transformArg3(targetValue) } // 后续处理逻辑 }
命名分组无需记忆分组索引,直接通过group("target")获取目标值,同时每个分支的精准性不受影响。
内容的提问来源于stack exchange,提问作者Ablia
相关产品推荐
相关产品推荐

