最近因为工作中的一点需要,所以要利用正则表达式去匹配指定的字符串并完成替换,因为很久写类似功能我先查了下网上写的博客,发现都是不太明确,甚至个别人竟然把错误的理解放到了博客里,所以想写一篇简单的介绍。
其实我最主要想说的是matcher.find()的方法和matcher.group()以及matcher.group(int index)等三个方法。
首先matcher.find()的返回值时boolean类型,当结果为true时,证明目标字符串中存在我们想要捕获的字符串,反之false是没有匹配的字符串。那么要怎么取到匹配的值呢,这时就要用到matcher.group()和错误的matcher.group(int index)方法。为什么说matcher.group(int index)是错误的呢?别急,这里就是我在网上踩到的雷。下面是错误的代码:
String regEx = "<a>([\s\S]*?)</a>";
String s = "<a>123</a><a>456</a><a>789</a>";
Pattern pat = Pattern.compile(regEx);
Matcher mat = pat.matcher(s);
boolean rs = mat.find();
for(int i=1;i<=mat.groupCount();i++){
System.out.println(mat.group(i));
}
这段代码表面的逻辑是在使用matcher.find()方法后,会生成类似数组一样存在的matcher.group()容器,然后通过matcher.groupCount()获取容器长度,然后从1开始遍历取到匹配到的字符串,但这是错误的!!!!!!简直误人子弟!
下面是我写的简单代码:
/**
* 捕获并替换成指定内容
*
* @param contentStr
* @param keyConstent
* @return
*/
private static String getReplayceStr( String contentStr, String keyConstent) {
//正则表达式
String regex = "\\$\\{.*?\\}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(contentStr);
while (matcher.find()) {
contentStr = contentStr.replaceAll("\\$\\{" + getKey(matcher.group()) + "\\}",
keyConstent);
}
return contentStr;
}
private static String getKey(String title) {
title = title.substring(2, title.length() - 1);
return title;
}
正常来讲我们在使用matcher.find()使用后,的确是通过matcher.group()来捕获匹配到的字符串而且每调用一次下次调用索引会移到下一个匹配的字符串,但是matcher.group(int index)并不是一个取到第几个匹配的字符串方法,这个方法是干嘛的呢?举个例子
比如我们的要匹配的字符串是"a(pp)l(e)",如果我们利用matcher.group()方法,取到的是和"apple"一致的字符串,而用matcher.group(1)取到的是和"pp"一致的字符串,用matcher.group(2)取到的是和"e"一致的字符串,也就是说matcher.group(int index)方法是为了实现子检索的功能。matcher.group()和matcher.group(0)功能基本一致。
至于matcher.groupCount()指的是matcher.group(int index)中的index,也就是本次检索哪组表达式找到了匹配值。
以上是我个人结合经历的一些认识,希望能帮到需要的人,如果有错误欢迎指出。
其实我最主要想说的是matcher.find()的方法和matcher.group()以及matcher.group(int index)等三个方法。
首先matcher.find()的返回值时boolean类型,当结果为true时,证明目标字符串中存在我们想要捕获的字符串,反之false是没有匹配的字符串。那么要怎么取到匹配的值呢,这时就要用到matcher.group()和错误的matcher.group(int index)方法。为什么说matcher.group(int index)是错误的呢?别急,这里就是我在网上踩到的雷。下面是错误的代码:
String regEx = "<a>([\s\S]*?)</a>";
String s = "<a>123</a><a>456</a><a>789</a>";
Pattern pat = Pattern.compile(regEx);
Matcher mat = pat.matcher(s);
boolean rs = mat.find();
for(int i=1;i<=mat.groupCount();i++){
System.out.println(mat.group(i));
}
这段代码表面的逻辑是在使用matcher.find()方法后,会生成类似数组一样存在的matcher.group()容器,然后通过matcher.groupCount()获取容器长度,然后从1开始遍历取到匹配到的字符串,但这是错误的!!!!!!简直误人子弟!
下面是我写的简单代码:
/**
* 捕获并替换成指定内容
*
* @param contentStr
* @param keyConstent
* @return
*/
private static String getReplayceStr( String contentStr, String keyConstent) {
//正则表达式
String regex = "\\$\\{.*?\\}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(contentStr);
while (matcher.find()) {
contentStr = contentStr.replaceAll("\\$\\{" + getKey(matcher.group()) + "\\}",
keyConstent);
}
return contentStr;
}
private static String getKey(String title) {
title = title.substring(2, title.length() - 1);
return title;
}
正常来讲我们在使用matcher.find()使用后,的确是通过matcher.group()来捕获匹配到的字符串而且每调用一次下次调用索引会移到下一个匹配的字符串,但是matcher.group(int index)并不是一个取到第几个匹配的字符串方法,这个方法是干嘛的呢?举个例子
比如我们的要匹配的字符串是"a(pp)l(e)",如果我们利用matcher.group()方法,取到的是和"apple"一致的字符串,而用matcher.group(1)取到的是和"pp"一致的字符串,用matcher.group(2)取到的是和"e"一致的字符串,也就是说matcher.group(int index)方法是为了实现子检索的功能。matcher.group()和matcher.group(0)功能基本一致。
至于matcher.groupCount()指的是matcher.group(int index)中的index,也就是本次检索哪组表达式找到了匹配值。
以上是我个人结合经历的一些认识,希望能帮到需要的人,如果有错误欢迎指出。