正则匹配问题:如何修正正则提取最后下划线与点之间的内容
解决正则匹配问题:提取最后一个下划线与点之间的内容
你的问题出在原正则的惰性匹配会捕获第一个下划线到点之间的所有内容,包括中间的下划线。要提取最后一个下划线和点之间的文本,我们可以调整正则的匹配逻辑,用贪婪匹配定位到最后一个下划线,再捕获目标内容。
修正后的正则表达式
有两种常用写法,都能满足需求:
- 贪婪匹配定位最后一个下划线(推荐,更直观)
Pattern MY_PATTERN = Pattern.compile(".*_(.*?)\\.");
- 否定前瞻确保匹配最后一个下划线
Pattern MY_PATTERN = Pattern.compile("_(?!.*_)(.*?)\\.");
代码示例
下面是完整的测试代码,两种情况(单下划线、多下划线)都能正确输出目标内容:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexTest { public static void main(String[] args) { // 使用贪婪匹配的正则 Pattern greedyPattern = Pattern.compile(".*_(.*?)\\."); // 测试多下划线场景 Matcher matcher1 = greedyPattern.matcher("pet_te_you.txt"); while (matcher1.find()) { String type = matcher1.group(1); System.out.println(type); // 输出: you } // 测试单下划线场景 Matcher matcher2 = greedyPattern.matcher("Pet_you.txt"); while (matcher2.find()) { String type = matcher2.group(1); System.out.println(type); // 输出: you } } }
原理说明
- 对于
.*_(.*?)\\.:.*是贪婪匹配,会尽可能匹配到最后一个下划线之前的所有字符,然后(.*?)捕获这个下划线之后到第一个点之间的内容,刚好就是你需要的部分。 - 对于
_(?!.*_)(.*?)\\.:(?!.*_)是否定前瞻断言,它会确保当前匹配的下划线后面不再有其他下划线,这样就只会选中最后一个下划线,再捕获后续到点的内容。
两种写法都能解决你的问题,第一种更简洁易懂,适合大多数场景。
内容的提问来源于stack exchange,提问作者Moudiz
相关产品推荐
相关产品推荐

