伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

String.replaceAll方法,正则妙用

来源:本站原创 浏览:132次 时间:2021-12-18



更多精彩文章。

《微服务不是全部,只是特定领域的子集》

《“分库分表" ?选型和流程要慎重,否则会失控》

这么多监控组件,总有一款适合你

《使用Netty,我们到底在开发些什么?》

《这可能是最中肯的Redis规范了》

《程序员画像,十年沉浮》

最有用系列:

《Linux生产环境上,最常用的一套“vim“技巧》

《Linux生产环境上,最常用的一套“Sed“技巧》

《Linux生产环境上,最常用的一套“AWK“技巧》

如果你认同这些知识,欢迎关注微信公众号小姐姐味道

ID:xjjdog


我通常是不太关心代码的具体实现的,因为我的开发语言很杂,倾向于一些最简单通用的方式去解决。今儿不小心在群里看到一位朋友发了下面的java代码,感觉自己还是很局限很无知的:

String str1 = "createTime";String str2 = "createTimeAt";String regex = "([A-Z])+";System.out.println(str1.replaceAll(regex, "_$1").toLowerCase());System.out.println(str2.replaceAll(regex, "_$1").toLowerCase());//result//create_time//create_time_at复制代码

通过输出可以看到,这段代码的作用是把驼峰命名格式的字符串替换成下划线分割,这个功能比较简单,但是吸引我的却是他的代码。

"createTime".replaceAll("([A-Z]+)","_$1")复制代码

这行代码简单的很,就是调用了String类的replaceAll方法,方法的第一个参数是正则表达式,第二个参数是将要被替换成的新值。

让我惊奇的是他代码中,replaceAll的第二个参数,也就是JDK文档中名为replacement的参数,竟然是_$1。这是什么鬼?还支持类似占位符这样的东西?我一直都不知道。

问题探索

由于之前研究过一段正则表达式,通过观察replaceAll的第一个参数([A-Z]+),我猜想,这个应该是用到了正则表达式的分组,对应JDK中,就是java.util.regex.Matcher类的group()方法。

在Linux的Sed命令上,就使用&进行了一些替换,道理应该是相通的。

于是看了下String.replaceAll方法是如何实现的。 JDK:

public String replaceAll(String regex, String replacement) {return Pattern.compile(regex).matcher(this).replaceAll(replacement);}复制代码

哦,原来它底层就是用了Matcher,只不过用的是Matcher自己的replaceAll方法。去看它的文档,这个方法的参数果然有鬼,看下面实现代码。

public String replaceAll(String replacement) {        reset();        boolean result = find();if (result) {            StringBuilder sb = new StringBuilder();do {                appendReplacement(sb, replacement);                result = find();            } while (result);            appendTail(sb);return sb.toString();        }return text.toString();    }复制代码

里面关键的部分就是文档中说的appendReplacement方法,然后可以看到详细的描述文档。

看到这里明白了,原来这个方法的replacement参数可以通过$字符来指代Matcher通过正则匹配得到的分组,支持name和number 两种方式,这里对应的就是Matcher类的group(name)和group(int)两个方法。

结论

1、String的replaceAll方法实际上是通过java.util.regex.Matcher类的replaceAll()方法实现的。
2、java.util.regex.Matcher类的replaceAll方法又是通过调用appendReplacement方法实现替换逻辑3、Matcher类的appendReplacement方法的replacement参数支持通过$符号来指代Matcher匹配的分组

下面这串代码,就是使用Matcher类分组的一个最佳实践。

String data = "哈哈哈,xjjdog的手机号码是:12345678901,你会打给我吗";//通过Matcher的分组功能,可以提取出上面字符串中的手机号Matcher matcher = Pattern.compile(".*(我的手机号码是:([0-9]{11}))").matcher(data);while (matcher.find()) {    System.out.println("G0:" + matcher.group(0));    System.out.println("G1:" + matcher.group(1));    System.out.println("G2:" + matcher.group(2));}//result//G0:哈哈哈,xjjdog的手机号码是:12345678901//G1:xjjdog的手机号码是:12345678901//G2:12345678901复制代码

group(0)表示整个字符串
group(1)表示第一个匹配的,上面的例子中就是(我的手机号码是:([0-9]{11}))部分
group(2)表示第二个匹配的,上面的例子中就是([0-9]{11})部分

使用分组可以用来提取字符串中的目标字符串值,很好用!

几个例子

下面是几个例子,大家可以触类旁通。

驼峰转下划线命名
public static String camelToUnderline(String camelName) {return camelName.replaceAll("([A-Z]+)", "_$1").toLowerCase();}复制代码
下划线转驼峰

这个稍微麻烦点,是模仿者Matcher.replaceAll方法写的。

public static String underlineToCamel(String underlineName) {        Matcher matcher = Pattern.compile("(_[a-z]{1})").matcher(underlineName);        StringBuffer result = new StringBuffer();while (matcher.find()) {            String replacement = matcher.group(1);            matcher.appendReplacement(result, replacement.replace("_", "").toUpperCase());        }        matcher.appendTail(result);return result.toString();}复制代码

另外,Mybatis Gener�ֽ�,���ator插件源码中的也提供了类似方法(JavaBeansUtil.getCamelCaseString),这里做了下简单修改

 public static String getCamelCaseString(String inputString) {        StringBuilder sb = new StringBuilder();        boolean nextUpperCase = false;for (int i = 0; i < inputString.length(); i++) {            char c = inputString.charAt(i);            switch (c) {case '_':case '-':case '@':case '$':case '#':case ' ':case '/':case '&':if (sb.length() > 0) {                        nextUpperCase = true;                    }break;                default:if (nextUpperCase) {                        sb.append(Character.toUpperCase(c));                        nextUpperCase = false;                    } else {                        sb.append(Character.toLowerCase(c));                    }break;            }        }return sb.toString();    }复制代码

没有复杂的正则参与,速度显而快了不少。

End

看一些优秀的开源代码,确实能够了解到一些实用的技巧。这比起自己费劲心力重复制造一些轮子,要高效的多。时间要用在刀刃上,但不是用来切豆腐。



  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net