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

Java字符串 正則表達式詳解

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

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

以一個問題引出本博客的內(nèi)容。問題是:檢查一個字符串是否以大寫字母開頭,以句號結(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.*[\.] 就 是 正 則 表 達 式 , 用 來 匹 配 字 符 串 。 代 表 一 行 的 起 始 , [ A − Z ] 表 是 A 到 Z 任 何 的 字 母 , 就是正則表達式,用來匹配字符串。^代表一行的起始,[A-Z]表是A到Z任何的字母, 就是正則表達式,用來匹配字符串。代表一行的起始,[A−Z]表是A到Z任何的字母,表示的一行的結(jié)束。

一、規(guī)則表

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

1.字符

B 指定字符B
\xhh 十六進制為oxhh的字符
\uhhhh 十六進制表示為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 前一個匹配的結(jié)束

4.邏輯操作符

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

5.量詞

貪婪型 勉強型 占有型 如何匹配
X? X?? X?+ 一個或零個X
X* X*? X*+ 零個或多個X
X+ X+? X++ 一個或多個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類的實例獲取—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類對象實例。

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

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

通過compile方法生成一個Pattern類實例對象,然后將想要匹配的字段傳入Pattern對象的matcher()方法,matcher()方法會返回生成一個Matcher類實例對象,這個對象也有很多對應(yīng)的方法。所以Matcher類也是無法通過new去創(chuàng)建一個實例的,而是通過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();
}

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

方式一:

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

當是從源碼中可以看出matches方法是類靜態(tài)方法,所以沒必要使用Macher類實例對象來調(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ù)組可以為任意長度,并且將丟棄尾部空字符串。

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

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

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

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

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

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

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

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

Pattern.CASE_INSENSITIVE、Pattern.COMMENTSPattern.MULTILINE這三個比較常用。

三、Matcher類

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

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

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

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

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

總結(jié)

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

相關(guān)文章

  • 詳解Java Web如何限制訪問的IP的兩種方法

    詳解Java Web如何限制訪問的IP的兩種方法

    這篇文章主要介紹了詳解Java Web如何限制訪問的IP的兩種方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • java編程實現(xiàn)屏幕截圖(截屏)代碼總結(jié)

    java編程實現(xiàn)屏幕截圖(截屏)代碼總結(jié)

    這篇文章主要介紹了java編程實現(xiàn)屏幕截圖(截屏)代碼,結(jié)合3個實例總結(jié)分析了Java截屏?xí)r頁面抓取及圖片保存的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • Java的云打印Lodop

    Java的云打印Lodop

    這篇文章主要介紹了Java的云打印Lodop 的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-07-07
  • Mybatis 復(fù)雜對象resultMap的使用

    Mybatis 復(fù)雜對象resultMap的使用

    這篇文章主要介紹了Mybatis 復(fù)雜對象resultMap的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java網(wǎng)上圖書商城(2)Category模塊

    java網(wǎng)上圖書商城(2)Category模塊

    這篇文章主要介紹了java網(wǎng)上圖書商城,Category模塊,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Java設(shè)計模式之淺談模板方法模式

    Java設(shè)計模式之淺談模板方法模式

    今天給大家?guī)淼氖顷P(guān)于Java設(shè)計模式的相關(guān)知識,文章圍繞著Java模板方法展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • springboot集成mybatisplus的方法

    springboot集成mybatisplus的方法

    這篇文章主要為大家詳細介紹了springboot集成mybatisplus的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Mybatis延遲加載原理和延遲加載配置詳解

    Mybatis延遲加載原理和延遲加載配置詳解

    這篇文章主要介紹了Mybatis延遲加載原理和延遲加載配置詳解,MyBatis中的延遲加載,也稱為懶加載,是指在進行表的關(guān)聯(lián)查詢時,按照設(shè)置延遲規(guī)則推遲對關(guān)聯(lián)對象的select查詢,需要的朋友可以參考下
    2023-10-10
  • Java多線程實現(xiàn)同時輸出

    Java多線程實現(xiàn)同時輸出

    這篇文章主要介紹了Java多線程實現(xiàn)同時打印的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • IDEA中Maven報錯Cannot resolve xxx的解決方法匯總(親測有效)

    IDEA中Maven報錯Cannot resolve xxx的解決方法匯總(親測有效)

    在IDEA中的pom文件中添加了依賴,并且正確加載了相應(yīng)依賴,pom文件沒有報紅,看起來像是把所有依賴庫全部加載進來了,但是代碼中使用依賴的類庫使報紅,本文給大家介紹了IDEA中Maven報錯Cannot resolve xxx的解決方法匯總,需要的朋友可以參考下
    2024-06-06

最新評論

大安市| 盖州市| 乌兰察布市| 宁都县| 洛川县| 塔城市| 洞头县| 犍为县| 雅安市| 湛江市| 上杭县| 安远县| 汝州市| 蒙山县| 宝鸡市| 宾川县| 高要市| 灵武市| 锦州市| 徐水县| 本溪| 工布江达县| 清原| 涪陵区| 磐安县| 共和县| 陕西省| 色达县| 九龙坡区| 福安市| 岫岩| 蒙阴县| 南丰县| 阿克陶县| 延安市| 齐齐哈尔市| 元江| 永丰县| 贵德县| 凌海市| 亳州市|