欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java字符串 正則表達(dá)式詳解

 更新時(shí)間:2021年09月08日 10:13:06   作者:半城抹茶  
這篇文章主要介紹了java使用正則表達(dá)式查找包含的字符串功能,結(jié)合具體實(shí)例形式分析了java針對(duì)字符串匹配查找的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下

在日常Java后端開發(fā)過程中,免不了對(duì)數(shù)據(jù)字段的解析,自然就少不了對(duì)字符串的操作,這其中就包含了正則表達(dá)式這一塊的內(nèi)容,這里面涉及Java包中Pattern類和Macher類,本篇博客就針對(duì)這一塊內(nèi)容和常見的用法進(jìn)行總結(jié),本博客主要的參考資料是《Java編程思想》第4版。

以一個(gè)問題引出本博客的內(nèi)容。問題是:檢查一個(gè)字符串是否以大寫字母開頭,以句號(hào)結(jié)尾

String len="^[A-Z].*[\\.]$";
System.out.println("Taaa.".matches(len));//true
System.out.println("taaa.".matches(len));//false
System.out.println("Taaa".matches(len));//false

1.*[\.] 就 是 正 則 表 達(dá) 式 , 用 來 匹 配 字 符 串 。 代 表 一 行 的 起 始 , [ A − Z ] 表 是 A 到 Z 任 何 的 字 母 , 就是正則表達(dá)式,用來匹配字符串。^代表一行的起始,[A-Z]表是A到Z任何的字母, 就是正則表達(dá)式,用來匹配字符串。代表一行的起始,[A−Z]表是A到Z任何的字母,表示的一行的結(jié)束。

一、規(guī)則表

規(guī)則表定義正則表達(dá)式該怎么寫。這類東西不需要刻意去記,用的時(shí)候去寫就好,用多了自然就記住了。

1.字符

B 指定字符B
\xhh 十六進(jìn)制為oxhh的字符
\uhhhh 十六進(jìn)制表示為oxhhhh的Unicode字符
\t 制表符Tab
\n 換行符
\r 回車
\f 換頁
\e 轉(zhuǎn)義

2.字符類 .

. 任意字符
[abc] 包含a、b和c的任何字符(和a|b|c作用相同)
[^abc] 除了a、b和c之外的任何字符(否定)
[a-zA-Z] 從a到z或從A到Z的任何字符(范圍)
[abc[hij]] 任意a、b、c、h、i和j字符(與a|b|c|h|i|j作用相同)
[a-z&&[hij]] 任意h、i或j
\s 空白符(空格、tab、換行、換頁和回車)
\S 非空白符
\d 數(shù)字
\D 非數(shù)字
\w 詞字符[a-zA-Z0-9]
\W 非詞字符

3.邊界匹配符

^ 一行的起始
$ 一行的結(jié)束
\b 詞的邊界
\B 非詞的邊界
\G 前一個(gè)匹配的結(jié)束

4.邏輯操作符

XY Y跟在X后面
X|Y X或Y
(X) 捕獲組

5.量詞

貪婪型 勉強(qiáng)型 占有型 如何匹配
X? X?? X?+ 一個(gè)或零個(gè)X
X* X*? X*+ 零個(gè)或多個(gè)X
X+ X+? X++ 一個(gè)或多個(gè)X
X{n} X{n}? X{n}+ 恰好n次X
X{n,} X{n,}? X{n,}+ 至少n次X
X{n,m} X{n,m}? X{n,m}+ X至少n次,且不超過m次

二、Pattern類

1.Pattern類的實(shí)例獲取—compile方法

1.下面主要是Pattern類源碼下一些重要的方法

private Pattern(String p, int f) {
    pattern = p;
    flags = f;

    // to use UNICODE_CASE if UNICODE_CHARACTER_CLASS present
    if ((flags & UNICODE_CHARACTER_CLASS) != 0)
        flags |= UNICODE_CASE;

    // Reset group index count
    capturingGroupCount = 1;
    localCount = 0;

    if (!pattern.isEmpty()) {
        try {
            compile();
        } catch (StackOverflowError soe) {
            throw error("Stack overflow during pattern compilation");
        }
    } else {
        root = new Start(lastAccept);
        matchRoot = lastAccept;
    }
}

從Pattern類代碼可以看出構(gòu)造器是私有的,故無法使用new去獲得Pattern類對(duì)象實(shí)例。

仔細(xì)查詢Pattern類下代碼后發(fā)現(xiàn)通過靜態(tài)方法compile去獲取Pattern類的實(shí)例對(duì)象。

public static Pattern compile(String regex) {
    return new Pattern(regex, 0);
}

通過compile方法生成一個(gè)Pattern類實(shí)例對(duì)象,然后將想要匹配的字段傳入Pattern對(duì)象的matcher()方法,matcher()方法會(huì)返回生成一個(gè)Matcher類實(shí)例對(duì)象,這個(gè)對(duì)象也有很多對(duì)應(yīng)的方法。所以Matcher類也是無法通過new去創(chuàng)建一個(gè)實(shí)例的,而是通過matcher方法

public Matcher matcher(CharSequence input) {
    if (!compiled) {
        synchronized(this) {
            if (!compiled)
                compile();
        }
    }
    Matcher m = new Matcher(this, input);
    return m;
}
public static boolean matches(String regex, CharSequence input) {
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(input);
    return m.matches();
}

所以之前博客開頭那個(gè)問題,也可以用另外兩種方式實(shí)現(xiàn):

方式一:

Pattern len = Pattern.compile("^[A-Z].*[\\.]$");
Matcher matcher = len.matcher("Taaa.");
boolean matches = matcher.matches();
System.out.println(matches);

當(dāng)是從源碼中可以看出matches方法是類靜態(tài)方法,所以沒必要使用Macher類實(shí)例對(duì)象來調(diào)用方法??梢允褂茫?/p>

方式二:

System.out.println(Pattern.matches("^[A-Z].*[\\.]$","Taaa."));

2.split方法

下面是Split方法的源碼:

public String[] split(CharSequence input, int limit) {
    int index = 0;
    boolean matchLimited = limit > 0;
    ArrayList<String> matchList = new ArrayList<>();
    Matcher m = matcher(input);

    // Add segments before each match found
    while(m.find()) {
        if (!matchLimited || matchList.size() < limit - 1) {
            if (index == 0 && index == m.start() && m.start() == m.end()) {
                // no empty leading substring included for zero-width match
                // at the beginning of the input char sequence.
                continue;
            }
            String match = input.subSequence(index, m.start()).toString();
            matchList.add(match);
            index = m.end();
        } else if (matchList.size() == limit - 1) { // last one
            String match = input.subSequence(index,
                                             input.length()).toString();
            matchList.add(match);
            index = m.end();
        }
    }

    // If no match was found, return this
    if (index == 0)
        return new String[] {input.toString()};

    // Add remaining segment
    if (!matchLimited || matchList.size() < limit)
        matchList.add(input.subSequence(index, input.length()).toString());

    // Construct result
    int resultSize = matchList.size();
    if (limit == 0)
        while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
            resultSize--;
    String[] result = new String[resultSize];
    return matchList.subList(0, resultSize).toArray(result);
}

方法解析:

input:要拆分的字符序列;

limit:結(jié)果閾值;根據(jù)指定模式拆分輸入序列。

limit參數(shù)作用:

limit參數(shù)控制應(yīng)用模式的次數(shù),從而影響結(jié)果數(shù)組的長度。

如果 n 大于零,那么模式至多應(yīng)用 n- 1 次,數(shù)組的長度不大于 n,并且數(shù)組的最后條目將包含除最后的匹配定界符之外的所有輸入。

如果 n 非正,那么將應(yīng)用模式的次數(shù)不受限制,并且數(shù)組可以為任意長度。

如果 n 為零,那么應(yīng)用模式的次數(shù)不受限制,數(shù)組可以為任意長度,并且將丟棄尾部空字符串。

詳細(xì)講解:假設(shè) input=“boo:and:foo”,匹配符為"o",可知模式最多可應(yīng)用4次,數(shù)組的長度最大為5;

1、當(dāng)limit=-2時(shí),應(yīng)用模式的次數(shù)不受限制且數(shù)組可以為任意長度;推測(cè)模式應(yīng)用4次,數(shù)組的長度為5,數(shù)組為{“b”,"",":and:f","",""};

2、當(dāng)limit=2時(shí),模式至多應(yīng)用1次,數(shù)組的長度不大于 2,且第二個(gè)元素包含除最后的匹配定界符之外的所有輸入;推測(cè)模式應(yīng)用1次,數(shù)組的長度為2,數(shù)組為{“b”,“o:and:foo”};

3、當(dāng)limit=7時(shí),模式至多應(yīng)用6次,數(shù)組的長度不大于 7;推測(cè)模式應(yīng)用4次,數(shù)組的長度為5,數(shù)組為{“b”,"",":and:f","",""};

4、當(dāng)limit=0時(shí),應(yīng)用模式的次數(shù)不受限制,數(shù)組可以為任意長度,并且將丟棄尾部空字符串;推測(cè)模式應(yīng)用4次,數(shù)組的長度為3,數(shù)組為{“b”,"",":and:f"}。

這里m.find像迭代器,遍歷輸入字符串

3.Pattern中匹配標(biāo)記參數(shù)

編譯標(biāo)記 效果
Pattern.CANON_EQ 啟用規(guī)范等價(jià)。當(dāng)且僅當(dāng)兩個(gè)字符的“正規(guī)分解(canonicaldecomposition)”都完全相同的情況下,才認(rèn)定匹配。默認(rèn)情況下,不考慮“規(guī)范相等性(canonical equivalence)”。
Pattern.CASE_INSENSITIVE 啟用不區(qū)分大小寫的匹配。默認(rèn)情況下,大小寫不敏感的匹配只適用于US-ASCII字符集。這個(gè)標(biāo)志能讓表達(dá)式忽略大小寫進(jìn)行匹配,要想對(duì)Unicode字符進(jìn)行大小不敏感的匹配,只要將UNICODE_CASE與這個(gè)標(biāo)志合起來就行了。
Pattern.COMMENTS 模式中允許空白和注釋。在這種模式下,匹配時(shí)會(huì)忽略(正則表達(dá)式里的)空格字符(不是指表達(dá)式里的“\s”,而是指表達(dá)式里的空格,tab,回車之類)。注釋從#開始,一直到這行結(jié)束??梢酝ㄟ^嵌入式的標(biāo)志來啟用Unix行模式。
Pattern.DOTALL 啟用dotall模式。在這種模式下,表達(dá)式‘.'可以匹配任意字符,包括表示一行的結(jié)束符。默認(rèn)情況下,表達(dá)式‘.'不匹配行的結(jié)束符。
Pattern.MULTILINE 啟用多行模式。在這種模式下,‘^'和‘ ' 分 別 匹 配 一 行 的 開 始 和 結(jié) 束 。 此 外 , ‘ ' 仍 然 匹 配 字 符 串 的 開 始 , ‘ '分別匹配一行的開始和結(jié)束。此外,‘^'仍然匹配字符串的開始,‘ '分別匹配一行的開始和結(jié)束。此外,‘'仍然匹配字符串的開始,‘'也匹配字符串的結(jié)束。默認(rèn)情況下,這兩個(gè)表達(dá)式僅僅匹配字符串的開始和結(jié)束。
Pattern.UNICODE_CASE 啟用Unicode感知的大小寫折疊。在這個(gè)模式下,如果你還啟用了CASE_INSENSITIVE標(biāo)志,那么它會(huì)對(duì)Unicode字符進(jìn)行大小寫不敏感的匹配。默認(rèn)情況下,大小寫不敏感的匹配只適用于US-ASCII字符集。
Pattern.UNIX_LINES 啟用Unix行模式。在這個(gè)模式下,只有‘\n'才被認(rèn)作一行的中止,并且與‘.'、‘^'、以及‘$'進(jìn)行匹配。

Pattern.CASE_INSENSITIVE、Pattern.COMMENTSPattern.MULTILINE這三個(gè)比較常用。

三、Matcher類

對(duì)照Matcher構(gòu)造器源碼,可知構(gòu)造器將Pattern對(duì)象的引用賦于Matcher中變量parentPattern,目標(biāo)字符串賦于變量text;并創(chuàng)建了數(shù)組groups和locals 。

數(shù)組groups是組使用的存儲(chǔ)。存儲(chǔ)的是當(dāng)前匹配的各捕獲組的first和last信息。

groups[0]存儲(chǔ)的是組零的first,groups[1]存儲(chǔ)的是組零的last,groups[2]存儲(chǔ)的是組1的first,groups[3]存儲(chǔ)的是組1的last,依次類推。

Matcher類的方法非常多,這里就不對(duì)每個(gè)方法的源碼進(jìn)行詳細(xì)的解讀了,后續(xù)如果有空會(huì)深入研究一下。將常用方法總結(jié)如下

方法名 功能作用
public int groupCount() 返回此匹配器中的捕獲組數(shù)
public String group() 實(shí)際上是調(diào)用了group(int group) ,只不過參數(shù)是0
public String group(int group) 返回當(dāng)前查找而獲得的與組匹配的所有子串內(nèi)容
public int start() 返回當(dāng)前匹配的子串的第一個(gè)字符在目標(biāo)字符串中的索引位置
public int start(int group) 返回當(dāng)前匹配的指定組中的子串的第一個(gè)字符在目標(biāo)字符串中的索引位置 。
public int end() 返回當(dāng)前匹配的子串的最后一個(gè)字符的下一個(gè)位置在目標(biāo)字符串中的索引位置 。
public int end(int group) 返回當(dāng)前匹配的的指定組中的子串的最后一個(gè)字符的下一個(gè)位置在目標(biāo)字符串中的索引位置
public boolean find() 在目標(biāo)字符串里查找下一個(gè)匹配子串
public boolean find(int start) 重置此匹配器,然后嘗試查找匹配該模式,從指定的位置開始查找下一個(gè)匹配的子串
public int regionStart() 報(bào)告此匹配器區(qū)域的開始索引。
public int regionEnd() 報(bào)告此匹配器區(qū)域的結(jié)束索引(不包括)。
public Matcher region(int start,int end) 設(shè)置此匹配器的區(qū)域限制。重置匹配器,然后設(shè)置區(qū)域,使其從start參數(shù)指定的索引開始,到 end參數(shù)指定的索引結(jié)束(不包括end索引處的字符)。
public boolean lookingAt() 從目標(biāo)字符串開始位置進(jìn)行匹配。只有在有匹配且匹配的某一子串中包含目標(biāo)字符串第一個(gè)字符的情況下才會(huì)返回true。
public boolean matches() 只有完全匹配時(shí)才會(huì)返回true。
public Matcher appendReplacement(StringBuffer sb, String replacement) 將當(dāng)前匹配子串替換為指定字符串,并將從上次匹配結(jié)束后到本次匹配結(jié)束后之間的字符串添加到一個(gè)StringBuffer對(duì)象中,最后返回其字符串表示形式。
public StringBuffer appendTail(StringBuffer sb) 將最后一次匹配工作后剩余的字符串添加到一個(gè)StringBuffer對(duì)象里。
public String replaceAll(String replacement) 將匹配的子串用指定的字符串替換。
public String replaceFirst(String replacement) 將匹配的第一個(gè)子串用指定的字符串替換。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • SpringBoot構(gòu)建ORM框架的方法步驟

    SpringBoot構(gòu)建ORM框架的方法步驟

    本文主要介紹了SpringBoot構(gòu)建ORM框架的方法步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • SpringBoot web靜態(tài)資源配置詳解

    SpringBoot web靜態(tài)資源配置詳解

    這篇文章主要介紹了SpringBoot web靜態(tài)資源配置詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • SpringBoot如何整合mybatis-generator-maven-plugin 1.4.0

    SpringBoot如何整合mybatis-generator-maven-plugin 1.4.0

    這篇文章主要介紹了SpringBoot整合mybatis-generator-maven-plugin 1.4.0的實(shí)現(xiàn)方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-01-01
  • Springboot+AOP實(shí)現(xiàn)返回?cái)?shù)據(jù)提示語國際化的示例代碼

    Springboot+AOP實(shí)現(xiàn)返回?cái)?shù)據(jù)提示語國際化的示例代碼

    這篇文章主要介紹了Springboot+AOP實(shí)現(xiàn)返回?cái)?shù)據(jù)提示語國際化的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • SpringCloud基于Feign的可編程式接口調(diào)用實(shí)現(xiàn)

    SpringCloud基于Feign的可編程式接口調(diào)用實(shí)現(xiàn)

    本文主要介紹了SpringCloud基于Feign的可編程式接口調(diào)用實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • ZIP4j 壓縮與解壓的實(shí)例詳解

    ZIP4j 壓縮與解壓的實(shí)例詳解

    這篇文章主要介紹了ZIP4j 壓縮與解壓的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • java時(shí)間戳轉(zhuǎn)日期格式的實(shí)現(xiàn)代碼

    java時(shí)間戳轉(zhuǎn)日期格式的實(shí)現(xiàn)代碼

    本篇文章是對(duì)java時(shí)間戳轉(zhuǎn)日期格式的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(57)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(57)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-08-08
  • Java使用Condition控制線程通信的方法實(shí)例詳解

    Java使用Condition控制線程通信的方法實(shí)例詳解

    這篇文章主要介紹了Java使用Condition控制線程通信的方法,結(jié)合實(shí)例形式分析了使用Condition類同步檢測(cè)控制線程通信的相關(guān)操作技巧,需要的朋友可以參考下
    2019-09-09
  • Java通過Socket實(shí)現(xiàn)簡單多人聊天室

    Java通過Socket實(shí)現(xiàn)簡單多人聊天室

    這篇文章主要為大家詳細(xì)介紹了Java通過Socket實(shí)現(xiàn)簡單多人聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04

最新評(píng)論