正则表达式在一个字符串上多次搜索、正则表达式匹配书名等

最近项目有个需求是这样的:

从字符串中匹配出全部书名,然后链接到对应数据库的书

如果 想匹配整个书名,包含书名号,如下

数据源:《张三(哈哈)》李四《王武》
想要匹配出的结果:《张三(哈哈)》    《王武》

使用正则表达式:《.*?》
最终结果:《张三(哈哈)》
重复多次匹配可以得到:《张三(哈哈)》    《王武》

如果 只想匹配书名,不包含书名号,如下

数据源:《张三(哈哈)》李四《王武》
想要匹配出的结果:张三、王武

使用正则表达式:(?<=《).*?(?=》)
最终结果:张三(哈哈)
重复多次匹配可以得到:张三(哈哈)    王武

第二种方式使用到了零向断言
https://deerchao.cn/tutorials/regex/regex.htm#lookaround

如下:

(?<=《).*?(?=》)

其中

(?<=字符A)  表示匹配字符A开头之后的
(?=字符B)   表示匹配字符B结尾之前的
.*?        表示匹配任意非换行符的字符,尽可能少匹配

(?<=《).*?(?=》) 表示匹配以书名号开头和结尾的内容,中间内容随意,但是尽可能少匹配

然后就是替换处理了

假设我们的需求是,给每本书都加上前缀编号,也就是 《水浒传》哈哈《西游记》编号为《书-1-水浒传》哈哈《书-2-西游记》

两种方法:

推荐方法:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.function.Function;
import java.util.regex.MatchResult;


public class Example {
    public static void main(String[] args) {
        final String regex = "(?<=《).*?(?=》)";
        final String string = "《张三(哈哈)》李四《王武》";

        final Pattern pattern = Pattern.compile(regex);
        final Matcher matcher = pattern.matcher(string);

        String res = matcher
                .replaceAll(new Function<MatchResult, String>() {
                    int i = 1;
                    @Override
                    public String apply(MatchResult matchResult) {
                        return "书-" + (i++) + "-" + matchResult.group();
                    }
                });
        
        // res = 《书-1-张三(哈哈)》李四《书-2-王武》        
        System.out.println("res = " + res);
    }
}

通用方法:

public static void main(String[] args) {
        final String regex = "(?<=《).*?(?=》)";
        final String string = "《张三(哈哈)》李四《王武》";

        final Pattern pattern = Pattern.compile(regex);
        final Matcher matcher = pattern.matcher(string);

        // 注:提前判断,避免每次不匹配还创建一个 StringBuilder 对象,
        // 每次会创建 content.length() 长度数组,会造成很多空间浪费
        if (!matcher.find()) {
            System.out.println("res = " + string);
        }

        matcher.reset();
        StringBuilder replacedResBuilder = new StringBuilder(string.length());
        int i = 1;
        while (matcher.find()) {
            matcher.appendReplacement(replacedResBuilder, "书-" + (i++) + "-" + matcher.group());
        }
        matcher.appendTail(replacedResBuilder);

		// res = 《书-1-张三(哈哈)》李四《书-2-王武》      
        System.out.println("res = " + replacedResBuilder.toString());
    }

参考文章

正则表达式教程网站

在线正则表达式匹配测试网站-支持各种语言,并且支持最新语法

https://stackoverflow.com/questions/4892452/regex-match-multiple-times-in-string

https://stackoverflow.com/questions/9605716/java-regular-expression-find-and-replace

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值