String.replaceAll方法,正则妙用

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

  

 

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

  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:

  

 

  哦,原来它底层就是用了Matcher,只不过用的是Matcher自己的replaceAll方法。

  去看它的文档,这个方法的参数果然有鬼,看下面实现代码。

  

 

  里面关键的部分就是文档中说的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类分组的一个最佳实践。

  

 

  group(0)表示整个字符串

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

  group(2)表示第二个匹配的,上面的例子中就是([0-9]{11})部分

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

  几个例子

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

  驼峰转下划线命名

  

 

  下划线转beijin

  这个稍微麻烦点,是模仿者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 Generator插件源码中的也提供了类似方法(JavaBeansUtil.getCamelCaseString),这里做了下简单修改

  

 

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

  End

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

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值