java正则匹配及替换的一点思考

Java语言String类提供了简单的relace,replaceAll等方法:
这里写图片描述

在很多简单的情况下,这几个方法就能满足使用了。但是较为复杂的的情况下就不能仅靠这几个方法解决问题了。由于在实际工作中遇到的问题,引发如下的思考:

一个字符串含”hello world”,把hello 替换为hello hello,调用replaceAll会导致无穷死循环吗?java显然不会导致这样的问题发生,如果那样的话应该没人用java了,答案是不会,通过看replaceAll的源码了解其算法,在String内部,执行replaceAll的时候是在原位置执行替换的,有记录起始位置的指针,不会导致死循环,但是把hello替换为”hello hello”(多加几个空格),是会导致结果能出现3个hello的,这显然不是我们期望的结果。

这其实要实现替换的新旧字符串存在一定包含关系的替换问题,比如一个文件里有很多ip,我们要把他替换,比如10.10.10.101替换成10.10.10.10,这里后者是前者的一个字串,用简单的replcae和replaceAll不能很好的解决问题。

要想面对特殊情况也能正确的替换,最好是新建一个StringBuffer,逐字符遍历被匹配替换的string,把最新的结果保存在StringBugffer,最后才用StringBuffer返回结果。其实java的正则实现了这样的方法,涉及到Match类,一个例子程序:

public static boolean update(String file,Map<String,String> changes){
    try {
        Path path = Paths.get(file);
        if(Files.notExists(path)){
            System.out.println(String.format("file %s does does not exist",file));
            return false;
        }
        if(!Files.isWritable(path)){
            System.out.println(String.format("can not write file %s", file));
            return false;
        }
        List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
        List<String> newLines = new ArrayList<>();
        Iterator<String> iterator = lines.iterator();
        while(iterator.hasNext()){
            Matcher matcher = PATTERN.matcher(iterator.next());
            StringBuffer sb = new StringBuffer();
            while(matcher.find()){
                String str = matcher.group();
                if(ipChanges.containsKey(str)){
                    matcher.appendReplacement(sb,changes.get(str));
                }
            }
            matcher.appendTail(sb);
            newLines.add(new String(sb));
        }
        Files.write(path, newLines, StandardCharsets.UTF_8);
    } catch (IOException e) {
        System.out.println(String.format("IO exception happened when modify file %s",file));
        return false;
    }
    System.out.println(String.format("success modified file %s",file));
    return true;
}

用到了Match类的group、appendReplacement、appendTail等方法,这几个方法应该就是用于比较复杂的匹配及替换的场景的吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值