Java正则匹配逻辑改写为Stream实现及no match报错解决
报错原因
- 你在
filter和后续map操作中两次调用pattern.matcher(),生成了两个完全独立的Matcher实例。filter阶段调用过find()的Matcher不会保留状态到map阶段,新的Matcher未执行find()就直接调用group(),自然抛出no match found异常。 - 原始for循环使用
while(matcher.find())支持从单个字符串中提取多个符合规则的ID,你之前的Stream写法只能提取单个匹配结果,和原有逻辑不一致。
可行的Stream改写方案
我们可以使用flatMap直接处理单字符串多匹配的场景,无需跨操作传递Matcher,实现逻辑和原始for循环完全对齐:
Pattern pattern = Pattern.compile("[0-9]{15}"); List<String> catalogIds = IntStream.range(0, fragmentedHeader.length - 1) // 过滤下一项包含ads_management的索引 .filter(i -> fragmentedHeader[i + 1].contains("ads_management")) // 提取对应位置的header字符串 .mapToObj(i -> fragmentedHeader[i]) // 展开每个header的所有匹配结果 .flatMap(header -> { Matcher matcher = pattern.matcher(header); return matcher.results().map(MatchResult::group); }) .collect(Collectors.toList());
Java 8兼容写法
如果你的项目使用Java 8,不支持Matcher.results()方法,可以用如下兼容实现:
Pattern pattern = Pattern.compile("[0-9]{15}"); List<String> catalogIds = IntStream.range(0, fragmentedHeader.length - 1) .filter(i -> fragmentedHeader[i + 1].contains("ads_management")) .mapToObj(i -> fragmentedHeader[i]) .flatMap(header -> { Matcher matcher = pattern.matcher(header); List<String> matches = new ArrayList<>(); while (matcher.find()) { matches.add(matcher.group()); } return matches.stream(); }) .collect(Collectors.toList());
内容的提问来源于stack exchange,提问作者Xolo12er
相关产品推荐
相关产品推荐

