中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java正則表達式中Pattern類怎么用

發布時間:2022-01-12 17:44:56 來源:億速云 閱讀:123 作者:iii 欄目:開發技術

本篇內容主要講解“Java正則表達式中Pattern類怎么用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java正則表達式中Pattern類怎么用”吧!

    前言

    在Java中,java.util.regex包定義了正則表達式使用到的相關類,其中最主要的兩個類為:Pattern、Matcher:

    • Pattern 編譯正則表達式后創建一個匹配模式;

    • Matcher 使用Pattern實例提供的正則表達式對目標字符串進行匹配,是真正影響搜索的對象。。

    另加一個新的例外類,PatternSyntaxException,當遇到不合法的搜索模式時,會拋出例外。

    Pattern 概述

    聲明:public final class Pattern implements java.io.Serializable

    Pattern 類有final修飾,可知他不能被子類繼承。

    含義:模式類,正則表達式的編譯表示形式。

    注意:此類的實例是不可變的,可供多個并發線程安全使用。

    Pattern 匹配模式(Pattern flags)

    compile( )方法有一個版本,它需要一個控制正則表達式的匹配行為的參數:

    Pattern Pattern.compile(String regex, int flag)

    flag 的取值范圍

    字段說明
    Pattern.UNIX_LINES        unix行模式,大多數系統的行都是以\n結尾的,但是少數系統,比如Windows,卻是以\r\n組合來結尾的,啟用這個模式之后,將會只以\n作為行結束符,這會影響到^、$和點號(點號匹配換行符)。
            通過嵌入式標志表達式 (?d) 也可以啟用 Unix 行模式。
    Pattern.CASE_INSENSITIVE        默認情況下,大小寫不敏感的匹配只適用于US-ASCII字符集。這個標志能讓表達式忽略大小寫進行匹配。要想對Unicode字符進行大小不明感的匹配,只要將UNICODE_CASE與這個標志合起來就行了。
            通過嵌入式標志表達式(?i)也可以啟用不區分大小寫的匹配。
            指定此標志可能對性能產生一些影響。
    Pattern.COMMENTS ???????????????        這種模式下,匹配時會忽略(正則表達式里的)空格字符(不是指表達式里的”//s”,而是指表達式里的空格,tab,回車之類)和注釋(從#開始,一直到這行結束)。
            通過嵌入式標志表達式(?x) 也可以啟用注釋模式。
    Pattern.MULTILINE        默認情況下,輸入的字符串被看作是一行,即便是這一行中包好了換行符也被看作一行。當匹配“^”到“$”之間的內容的時候,整個輸入被看成一個一行。啟用多行模式之后,包含換行符的輸入將被自動轉換成多行,然后進行匹配。
            通過嵌入式標志表達式 (?m) 也可以啟用多行模式。
    Pattern.LITERAL        啟用字面值解析模式。
            指定此標志后,指定模式的輸入字符串就會作為字面值字符序列來對待。輸入序列中的元字符或轉義序列不具有任何特殊意義。
            標志 CASE_INSENSITIVE 和 UNICODE_CASE 在與此標志一起使用時將對匹配產生影響。其他標志都變得多余了。
            不存在可以啟用字面值解析的嵌入式標志字符。
    Pattern.DOTALL        在這種模式中,表達式 .可以匹配任何字符,包括行結束符。默認情況下,此表達式不匹配行結束符。
            通過嵌入式標志表達式 (?s) 也可以啟用此種模式(s 是 “single-line” 模式的助記符,在 Perl 中也使用它)。
    Pattern.UNICODE_CASE        在這個模式下,如果你還啟用了CASE_INSENSITIVE標志,那么它會對Unicode字符進行大小寫不敏感的匹配。默認情況下,大小寫不明感的匹配只適用于US-ASCII字符集。
            指定此標志可能對性能產生影響。
    Pattern.CANON_EQ        當且僅當兩個字符的正規分解(canonical decomposition)都完全相同的情況下,才認定匹配。比如用了這個標志之后,表達式a/u030A會匹配?。默認情況下,不考慮規范相等性(canonical equivalence)。
            指定此標志可能對性能產生影響。

    在這些標志里面,Pattern.CASE_INSENSITIVE,Pattern.MULTILINE,以及Pattern.COMMENTS是最有用的(其中Pattern.COMMENTS還能幫我們把思路理清楚,并且/或者做文檔)。注意,你可以用在表達式里插記號的方式來啟用絕大多數的模式。這些記號就在上面那張表的各個標志的下面。你希望模式從哪里開始啟動,就在哪里插記號。

    可以用OR (|)運算符把這些標志配合使用。

    代碼示例

    多行模式:Pattern.MULTILINE 示例

    我測試了一下,也就是說如果沒有 MULTILINE 標志的話, ^ 和 $ 只能匹配輸入序列的開始和結束;否則,就可以匹配輸入序列內部的行結束符。測試代碼如下:

    import java.util.regex.*;
    
    /**
     * 多行模式
     */
    public class ReFlags_MULTILINE {
    
        public static void main(String[] args) {
    
            // 注意里面的換行符
            String str = "hello world\r\n" + "hello java\r\n" + "hello java";
    
            System.out.println("===========匹配字符串開頭(非多行模式)===========");
            Pattern p = Pattern.compile("^hello");
            Matcher m = p.matcher(str);
            while (m.find()) {
                System.out.println(m.group() + "   位置:[" + m.start() + "," + m.end() + "]");
            }
    
            System.out.println("===========匹配字符串開頭(多行模式)===========");
            p = Pattern.compile("^hello", Pattern.MULTILINE);
            m = p.matcher(str);
            while (m.find()) {
                System.out.println(m.group() + "   位置:[" + m.start() + "," + m.end() + "]");
            }
    
            System.out.println("===========匹配字符串結尾(非多行模式)===========");
            p = Pattern.compile("java$");
            m = p.matcher(str);
            while (m.find()) {
                System.out.println(m.group() + "   位置:[" + m.start() + "," + m.end() + "]");
            }
    
            System.out.println("===========匹配字符串結尾(多行模式)===========");
            p = Pattern.compile("java$", Pattern.MULTILINE);
            m = p.matcher(str);
            while (m.find()) {
                System.out.println(m.group() + "   位置:[" + m.start() + "," + m.end() + "]");
            }
        }
    }

    ===========匹配字符串開頭(非多行模式)===========
    hello   位置:[0,5]
    ===========匹配字符串開頭(多行模式)===========
    hello   位置:[0,5]
    hello   位置:[13,18]
    hello   位置:[25,30]
    ===========匹配字符串結尾(非多行模式)===========
    java   位置:[31,35]
    ===========匹配字符串結尾(多行模式)===========
    java   位置:[19,23]
    java   位置:[31,35]

    忽略大小寫:Pattern.CASE_INSENSITIVE 示例

    有的時候,需要進行忽略大小寫的匹配。該例子實現匹配攝氏溫度和華氏溫度,對于以C、c、F和f結尾的溫度值都能匹配。

    import java.util.regex.Pattern;
    
    public class ReFlags_CASE_INSENSITIVE {
    
        public static void main(String[] args) {
    
    
            System.out.println("===========API忽略大小寫===========");
            String moneyRegex = "[+-]?(\\d)+(.(\\d)*)?(\\s)*[CF]";
            Pattern p = Pattern.compile(moneyRegex,Pattern.CASE_INSENSITIVE);
    
            System.out.println("-3.33c   " + p.matcher("-3.33c").matches());
            System.out.println("-3.33C   " + p.matcher("-3.33C").matches());
    
    
            System.out.println("===========不忽略大小寫===========");
            moneyRegex = "[+-]?(\\d)+(.(\\d)*)?(\\s)*[CF]";
            p = Pattern.compile(moneyRegex);
    
            System.out.println("-3.33c   " + p.matcher("-3.33c").matches());
            System.out.println("-3.33C   " + p.matcher("-3.33C").matches());
    
    
            System.out.println("===========正則內部忽略大小寫===========");
            moneyRegex = "[+-]?(\\d)+(.(\\d)*)?(\\s)*(?i)[CF]";
            p = Pattern.compile(moneyRegex);
    
            System.out.println("-3.33c   " + p.matcher("-3.33c").matches());
            System.out.println("-3.33C   " + p.matcher("-3.33C").matches());
    
    
            System.out.println("===========內部不忽略大小寫===========");
            moneyRegex = "[+-]?(\\d)+(.(\\d)*)?(\\s)*[CF]";
            p = Pattern.compile(moneyRegex);
    
            System.out.println("-3.33c   " + p.matcher("-3.33c").matches());
            System.out.println("-3.33C   " + p.matcher("-3.33C").matches());
        }
    }

    ===========API忽略大小寫===========
    -3.33c   true
    -3.33C   true
    ===========不忽略大小寫===========
    -3.33c   false
    -3.33C   true
    ===========正則內部忽略大小寫===========
    -3.33c   true
    -3.33C   true
    ===========內部不忽略大小寫===========
    -3.33c   false
    -3.33C   true

    啟用注釋:Pattern.COMMENTS 示例

    啟用注釋,開啟之后,正則表達式中的空格以及#號行將被忽略。

    import java.util.regex.Pattern;
    
    public class ReFlags_COMMENTS {
    
        public static void main(String[] args) {
    
            System.out.println("===========API啟用注釋===========");
            String comments = "    (\\d)+#this is comments.";
            Pattern p = Pattern.compile(comments, Pattern.COMMENTS);
            System.out.println("1234   " + p.matcher("1234").matches());
    
            System.out.println("===========不啟用注釋===========");
            comments = "    (\\d)+#this is comments.";
            p = Pattern.compile(comments);
            System.out.println("1234   " + p.matcher("1234").matches());
    
            System.out.println("===========正則啟用注釋===========");
            comments = "(?x)    (\\d)+#this is comments.";
            p = Pattern.compile(comments);
            System.out.println("1234   " + p.matcher("1234").matches());
    
            System.out.println("===========不啟用注釋===========");
            comments = "    (\\d)+#this is comments.";
            p = Pattern.compile(comments);
            System.out.println("1234   " + p.matcher("1234").matches());
    
        }
    }

    ===========API啟用注釋===========
    1234   true
    ===========不啟用注釋===========
    1234   false
    ===========正則啟用注釋===========
    1234   true
    ===========不啟用注釋===========
    1234   false

    可以看到,#號到行尾的注釋部分和前面的空白字符都被忽略了。正則表達式內置的啟用注釋為(?x)。

    啟用 dotall 模式:Pattern.DOTALL 示例

    啟用dotall模式,一般情況下,點號(.)匹配任意字符,但不匹配換行符,啟用這個模式之后,點號還能匹配換行符。

    import java.util.regex.Pattern;
    
    public class ReFlags_DOTALL {
    
        public static void main(String[] args) {
    
            System.out.println("===========API啟用DOTALL===========");
            String dotall = "<xml>(.)*</xml>";
            Pattern p = Pattern.compile(dotall, Pattern.DOTALL);
            System.out.println("<xml>\\r\\n</xml>   " + p.matcher("<xml>\r\n</xml>").matches());
    
            System.out.println("===========不啟用DOTALL===========");
            dotall = "<xml>(.)*</xml>";
            p = Pattern.compile(dotall);
            System.out.println("<xml>\\r\\n</xml>   " + p.matcher("<xml>\r\n</xml>").matches());
    
            System.out.println("===========正則啟用DOTALL===========");
            dotall = "(?s)<xml>(.)*</xml>";
            p = Pattern.compile(dotall);
            System.out.println("<xml>\\r\\n</xml>   " + p.matcher("<xml>\r\n</xml>").matches());
    
            System.out.println("===========不啟用DOTALL===========");
            dotall = "<xml>(.)*</xml>";
            p = Pattern.compile(dotall);
            System.out.println("<xml>\\r\\n</xml>   " + p.matcher("<xml>\r\n</xml>").matches());
    
        }
    }

    ===========API啟用DOTALL===========
    <xml>\r\n</xml>   true
    ===========不啟用DOTALL===========
    <xml>\r\n</xml>   false
    ===========正則啟用DOTALL===========
    <xml>\r\n</xml>   true
    ===========不啟用DOTALL===========
    <xml>\r\n</xml>   false

    平白字符模式 模式:Pattern.LITERAL 示例

    啟用這個模式之后,所有元字符、轉義字符都被看成普通的字符,不再具有其他意義。

    import java.util.regex.Pattern;
    
    public class ReFlags_LITERAL {
    
        public static void main(String[] args) {
    
            System.out.println(Pattern.compile("\\d", Pattern.LITERAL).matcher("\\d").matches());// true
            System.out.println(Pattern.compile("\\d", Pattern.LITERAL).matcher("2").matches());// false
    
            System.out.println(Pattern.compile("(\\d)+", Pattern.LITERAL).matcher("1234").matches());// false
            System.out.println(Pattern.compile("(\\d)+").matcher("1234").matches());// true
    
            System.out.println(Pattern.compile("(\\d){2,3}", Pattern.LITERAL).matcher("(\\d){2,3}").matches());// true
        }
    }

    附:貪婪匹配與懶惰匹配

    考慮這個表達式:a.*b,它將會匹配最長的以a開始,以b結束的字符串。如果用它來搜索aabab的話,它會匹配整個字符串aabab。這被稱為貪婪匹配。

    有時,我們更需要懶惰匹配,也就是匹配盡可能少的字符。前面給出的限定符都可以被轉化為懶惰匹配模式,只要在它后面加上一個問號?。這樣.*?就意味著匹配任意數量的重復,但是在能使整個匹配成功的前提下使用最少的重復。

    a.*?b匹配最短的,以a開始,以b結束的字符串。如果把它應用于aabab的話,它會匹配aab和ab。

    public static void main(String[] args) {
            String str = "北京市(海淀區)(朝陽區)";
            String paternStr = ".*(?=\\()";
            Pattern pattern = Pattern.compile(paternStr);
            Matcher matcher = pattern.matcher(str);
            if (matcher.find()) {
                System.out.println(matcher.group(0));
            }
    }

    上述方法的輸出為:北京市(海淀區)

    public static void main(String[] args) {
            String str = "北京市(海淀區)(朝陽區)";
            String paternStr = ".*?(?=\\()";
            Pattern pattern = Pattern.compile(paternStr);
            Matcher matcher = pattern.matcher(str);
            if (matcher.find()) {
                System.out.println(matcher.group(0));
            }
    }

    上述方法輸出:北京市

    到此,相信大家對“Java正則表達式中Pattern類怎么用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    潮州市| 高台县| 布拖县| 卢湾区| 丽水市| 景谷| 宜城市| 桦川县| 碌曲县| 保靖县| 调兵山市| 神农架林区| 兴城市| 黎平县| 赣榆县| 子洲县| 卢氏县| 延边| 临武县| 玛多县| 淮阳县| 易门县| 洱源县| 洪雅县| 泸州市| 潼关县| 鄂托克旗| 五原县| 唐海县| 黄大仙区| 涡阳县| 彰武县| 金秀| 策勒县| 明溪县| 静乐县| 平塘县| 嫩江县| 贡觉县| 满洲里市| 三穗县|