最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

String.replaceAll方法詳析(正則妙用)

 更新時(shí)間:2019年07月19日 08:33:03   作者:小姐姐養(yǎng)的狗  
這篇文章主要給大家介紹了關(guān)于String.replaceAll方法,正則妙用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

我通常是不太關(guān)心代碼的具體實(shí)現(xiàn)的,因?yàn)槲业拈_發(fā)語言很雜,傾向于一些最簡單通用的方式去解決。今兒不小心在群里看到一位朋友發(fā)了下面的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

通過輸出可以看到,這段代碼的作用是把駝峰命名格式的字符串替換成下劃線分割,這個(gè)功能比較簡單,但是吸引我的卻是他的代碼。

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

這行代碼簡單的很,就是調(diào)用了String類的replaceAll方法,方法的第一個(gè)參數(shù)是正則表達(dá)式,第二個(gè)參數(shù)是將要被替換成的新值。

讓我驚奇的是他代碼中,replaceAll的第二個(gè)參數(shù),也就是JDK文檔中名為replacement的參數(shù),竟然是_$1。這是什么鬼?還支持類似占位符這樣的東西?我一直都不知道。

問題探索

由于之前研究過一段正則表達(dá)式,通過觀察replaceAll的第一個(gè)參數(shù)([A-Z]+),我猜想,這個(gè)應(yīng)該是用到了正則表達(dá)式的分組,對(duì)應(yīng)JDK中,就是java.util.regex.Matcher類的group()方法。

在Linux的Sed命令上,就使用&進(jìn)行了一些替換,道理應(yīng)該是相通的。

于是看了下String.replaceAll方法是如何實(shí)現(xiàn)的。JDK:

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

哦,原來它底層就是用了Matcher,只不過用的是Matcher自己的replaceAll方法。

去看它的文檔,這個(gè)方法的參數(shù)果然有鬼,看下面實(shí)現(xiàn)代碼。

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();
  }

里面關(guān)鍵的部分就是文檔中說的appendReplacement方法,然后可以看到詳細(xì)的描述文檔。

看到這里明白了,原來這個(gè)方法的replacement參數(shù)可以通過$字符來指代Matcher通過正則匹配得到的分組,支持name和number 兩種方式,這里對(duì)應(yīng)的就是Matcher類的group(name)和group(int)兩個(gè)方法。

結(jié)論

1、String的replaceAll方法實(shí)際上是通過java.util.regex.Matcher類的replaceAll()方法實(shí)現(xiàn)的。

2、java.util.regex.Matcher類的replaceAll方法又是通過調(diào)用appendReplacement方法實(shí)現(xiàn)替換邏輯

3、Matcher類的appendReplacement方法的replacement參數(shù)支持通過$符號(hào)來指代Matcher匹配的分組

下面這串代碼,就是使用Matcher類分組的一個(gè)最佳實(shí)踐。

String data = "哈哈哈,xjjdog的手機(jī)號(hào)碼是:12345678901,你會(huì)打給我嗎";
//通過Matcher的分組功能,可以提取出上面字符串中的手機(jī)號(hào)
Matcher matcher = Pattern.compile(".*(xjjdog的手機(jī)號(hào)碼是:([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的手機(jī)號(hào)碼是:12345678901
//G1:xjjdog的手機(jī)號(hào)碼是:12345678901
//G2:12345678901

group(0)表示整個(gè)字符串

group(1)表示第一個(gè)匹配的,上面的例子中就是(我的手機(jī)號(hào)碼是:([0-9]{11}))部分

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

使用分組可以用來提取字符串中的目標(biāo)字符串值,很好用!

幾個(gè)例子

下面是幾個(gè)例子,大家可以觸類旁通。

駝峰轉(zhuǎn)下劃線命名

public static String camelToUnderline(String camelName) {
return camelName.replaceAll("([A-Z]+)", "_$1").toLowerCase();
}

下劃線轉(zhuǎn)駝峰

這個(gè)稍微麻煩點(diǎn),是模仿者M(jìn)atcher.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),這里做了下簡單修改

 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();
  }

沒有復(fù)雜的正則參與,速度顯而快了不少。

總結(jié)

看一些優(yōu)秀的開源代碼,確實(shí)能夠了解到一些實(shí)用的技巧。這比起自己費(fèi)勁心力重復(fù)制造一些輪子,要高效的多。時(shí)間要用在刀刃上,但不是用來切豆腐。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Java實(shí)戰(zhàn)之OutOfMemoryError異常問題及解決方法

    Java實(shí)戰(zhàn)之OutOfMemoryError異常問題及解決方法

    這篇文章主要介紹了Java實(shí)戰(zhàn)之OutOfMemoryError異常,主要結(jié)合著深入理解Java虛擬機(jī)一書當(dāng)中整理了本篇內(nèi)容,感興趣的朋友一起看看吧
    2022-04-04
  • SpringBoot整合SpringBoot-Admin實(shí)現(xiàn)監(jiān)控應(yīng)用功能

    SpringBoot整合SpringBoot-Admin實(shí)現(xiàn)監(jiān)控應(yīng)用功能

    本文主要介紹如何整合Spring Boot Admin,以此監(jiān)控Springboot應(yīng)用,文中有相關(guān)的示例代碼供大家參考,需要的朋友可以參考下
    2023-05-05
  • 一文徹底搞懂java多線程和線程池

    一文徹底搞懂java多線程和線程池

    當(dāng)一個(gè)服務(wù)器接受到大量短小線程的請(qǐng)求時(shí),使用線程池技術(shù)是非常合適的,它可以大大減少線程的創(chuàng)建和銷毀次數(shù),提高服務(wù)器的工作效率,這篇文章主要給大家介紹了如何通過一文徹底搞懂java多線程和線程池的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • 詳解Java?中的函數(shù)式接口

    詳解Java?中的函數(shù)式接口

    這篇文章主要為大家介紹了Java中的函數(shù)式接口,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助<BR>
    2021-12-12
  • java算法實(shí)現(xiàn)紅黑樹完整代碼示例

    java算法實(shí)現(xiàn)紅黑樹完整代碼示例

    這篇文章主要介紹了java算法實(shí)現(xiàn)紅黑樹完整代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • SpringBoot快速整合RabbitMq小案例(使用步驟)

    SpringBoot快速整合RabbitMq小案例(使用步驟)

    這篇文章主要介紹了SpringBoot快速整合RabbitMq小案例,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • Fluent Mybatis學(xué)習(xí)之Update語法實(shí)踐

    Fluent Mybatis學(xué)習(xí)之Update語法實(shí)踐

    Fluent MyBatis是一個(gè)MyBatis的增強(qiáng)工具,沒有對(duì)mybatis做任何修改。本篇文章將詳細(xì)介紹對(duì)Fluent Mybatis中的update語法進(jìn)行驗(yàn)證。代碼具有一定價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下
    2021-11-11
  • java生成指定范圍隨機(jī)數(shù)的多種代碼

    java生成指定范圍隨機(jī)數(shù)的多種代碼

    今天在寫代碼的時(shí)候需要用到一個(gè)生成指定范圍隨機(jī)數(shù)的函數(shù),百度了一下,發(fā)現(xiàn)了很多種方法,這里簡單為大家整理一下,方便需要的朋友
    2017-08-08
  • Java 繼承與多態(tài)超詳細(xì)梳理

    Java 繼承與多態(tài)超詳細(xì)梳理

    繼承就是可以直接使用前輩的屬性和方法。自然界如果沒有繼承,那一切都是處于混沌狀態(tài)。多態(tài)是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式或形態(tài)的能力。多態(tài)就是同一個(gè)接口,使用不同的實(shí)例而執(zhí)行不同操作
    2022-04-04
  • Mybatis分頁插件PageHelper的配置和簡單使用方法(推薦)

    Mybatis分頁插件PageHelper的配置和簡單使用方法(推薦)

    在使用Java Spring開發(fā)的時(shí)候,Mybatis算是對(duì)數(shù)據(jù)庫操作的利器了。這篇文章主要介紹了Mybatis分頁插件PageHelper的配置和使用方法,需要的朋友可以參考下
    2017-12-12

最新評(píng)論

马尔康县| 班玛县| 沾益县| 巴彦县| 黑水县| 景洪市| 赤水市| 成都市| 铜鼓县| 五寨县| 八宿县| 横峰县| 海伦市| 比如县| 驻马店市| 宣汉县| 奉节县| 滨海县| 林周县| 靖江市| 波密县| 海城市| 英山县| 张家川| 鄢陵县| 洛浦县| 新宾| 江山市| 百色市| 台中县| 霍邱县| 邛崃市| 聂荣县| 贵德县| 伽师县| 读书| 清河县| 鞍山市| 晋城| 阿克陶县| 孟津县|