遗留系统配置键格式匹配问题:正则表达式优化需求
解决配置键正则捕获数字后缀的问题
问题分析
你当前使用的正则表达式(.+[^_])(?:__(\d+))?采用贪婪匹配模式,遇到key__dd格式的键时,(.+[^_])会尽可能匹配到字符串最后一个非下划线字符(即数字后缀的最后一位),导致整个键(包括__dd部分)被纳入第一个捕获组,数字后缀无法被正确捕获。
修正后的正则表达式
针对合法配置键的拆分需求,改用非贪婪匹配即可解决问题,Java中对应的正则字符串为:
String regex = "^(.*?[^_])(?:__(\\d+))?$";
正则说明
^(.*?[^_]):非贪婪匹配主体部分,.*?会尽可能少地匹配字符,直到遇到__\d+后缀或字符串结尾;[^_]保证主体部分不以下划线结尾,符合配置键规则。(?:__(\\d+))?$:可选的数字后缀部分,__后跟一个或多个数字,作为第二个捕获组;?:表示该分组仅用于匹配不参与捕获,$限定后缀必须在字符串末尾。
测试验证
对合法示例的匹配结果:
foo_bar__2:捕获组1为foo_bar,捕获组2为2_foo_bar__2:捕获组1为_foo_bar,捕获组2为2foo:捕获组1为foo,捕获组2为null(对应默认值1)foo__42:捕获组1为foo,捕获组2为42
代码示例
import java.util.regex.Matcher; import java.util.regex.Pattern; public class ConfigKeyParser { public static void main(String[] args) { String[] testKeys = {"foo_bar__2", "_foo_bar__2", "foo", "foo--$%^##", "$%^#", "foo__42"}; Pattern pattern = Pattern.compile("^(.*?[^_])(?:__(\\d+))?$"); for (String key : testKeys) { Matcher matcher = pattern.matcher(key); if (matcher.matches()) { String mainKey = matcher.group(1); String numberStr = matcher.group(2); int value = numberStr != null ? Integer.parseInt(numberStr) : 1; System.out.printf("键:%s -> 主体:%s,值:%d%n", key, mainKey, value); } } } }
内容的提问来源于stack exchange,提问作者Eli Schneider
相关产品推荐
相关产品推荐

