“南风知我意,吹梦到西洲”
很多时候我们需要对文本进行替换,简单地使用replace方法就可以了。复杂的就需要使用正则;java提供了正则相关的类Pattern 和Matcher
-
基本语法这里就不在重复,不了解可以参考菜鸟教程:
https://www.runoob.com/java/java-regular-expressions.html
基本写法如下
// 正则表达式
String reg = "";
// 需要匹配的字符串
String str = "";
// 预编译
Pattern patten = Pattern.compile(reg);
// 进行匹配
Matcher matcher = patten.matcher(str);
/**
* matcher.find()为true表示匹配到,如果匹配到多个下一次循环偏移到下一个匹配
* 每一次匹配可以理解为一组,从0开始
*/
while (matcher.find()) {
// 疯狂操作
// 利用start和end我们可以确定匹配到的字符串的位置
// 当前匹配到的字符串的开始在原字符串的索引位置
matcher.start()
// 当前匹配到的字符串的结尾在原字符串的索引位置
matcher.end()
// 当前匹配到的字符串
matcher.group()
// 替换第一次匹配的数据
matcher.replaceFirst("");
// 替换所有匹配的数据
matcher.replaceAll("");
}
这里说几个需要注意的地方
-
正则需要进行预编译:
阿里巴巴java开发手册中有提到:
在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
我们尽量不要再方法里面定义:Pattern pattern = Pattern.compile(“规则”);如果定义在方法体内每次调用都会进行编译影响方法效率。 -
replaceFirst()和replaceAll()方法:
这两个方法要么替换所有,要么只替换第一次限制太大了,只适用于某些特殊的场景, -
start(), end(),group():
都可以传入一个int值取之前匹配的该方法内容,比如start(0)就表示第一次匹配到的字符串的开头在源字符串的位置
group(0)比较特殊它代表整个表达式
- 可以发现简单地替换不能满足我们的需求,正则还提供了两个替换的方法appendReplacement()和appendTail()
String chapterContent = ""
String line = "<br/>";
String regx = num_zh_str;
Pattern pattern = Pattern.compile(regx);
Matcher matcher = pattern.matcher(chapterContent);
StringBuffer chapterContentLine = new StringBuffer();
while (matcher.find()){
boolean equals = line.equals(chapterContent.indexOf(matcher.start() - line.length()));
if (!equals){
matcher.appendReplacement(chapterContentLine,line + matcher.group());
}else{
matcher.appendTail(chapterContentLine);
}
}
matcher.appendTail(chapterContentLine);
content.append(chapterName).append(chapterContentLine.toString());
我的目的是在匹配的的字符串前面加一个换行符”<br/>”,如果匹配字符前面已经有了换行符那就不要进行替换
matcher.group()就是匹配到的字符串,通过appendReplacement()方法将匹配的的字符串替换后,将字符串添加到一个StringBuffer中,
这里appendReplacement()方法只将匹配到的字符串添加到StringBuffer中,如果之前有匹配到的也会添加到StringBuffer中,但是没有匹配到的是不会添加到StringBuffer中的。所有我们需要在下面在调用matcher.appendTail(),以确保没有匹配到的也添加到StringBuffer中
这样我们的目的就实现了,相比replaceXXX,appendXXX更灵活
版权声明:本文为zlhmeng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。