Java基礎:正則表達式

相關閱讀

  1. Java基礎:String類
  2. Java字符串格式化
  3. Java基礎:正則表達式

1. 正則表達式概述

正則表達式,又稱正規表示法、常規表示法(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE),計算機科學的一個概念。正則表達式使用單個字符串來描述、匹配一系列符合某個句法規則的字符串。在很多文本編輯器里,正則表達式通常被用來檢索、替換那些符合某個模式的文本

許多程序設計語言都支持利用正則表達式進行字符串操作。例如,在Perl中就內建了一個功能強大的正則表達式引擎。正則表達式這個概念最初是由Unix中的工具軟件(例如sed和grep)普及開的。正則表達式通??s寫成“regex”,單數有regexp、regex,復數有regexps、regexes、regexen

正則表達式是對字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個“規則字符串”,這個“規則字符串”用來表達對字符串的一種過濾邏輯

1.1 給定一個正則表達式和另一個字符串,我們可以達到如下的目的

  • 給定的字符串是否符合正則表達式的過濾邏輯(稱作“匹配”)
  • 可以通過正則表達式,從字符串中獲取我們想要的特定部分

1.2 正則表達式的特點是

  • 靈活性、邏輯性和功能性非常的強;
  • 可以迅速地用極簡單的方式達到字符串的復雜控制。
  • 對于剛接觸的人來說,比較晦澀難懂。

由于正則表達式主要應用對象是文本,因此它在各種文本編輯器場合都有應用,小到著名編輯器EditPlus,大到Microsoft Word、Visual Studio等大型編輯器,都可以使用正則表達式來處理文本內容

2. 正則表達式基礎知識

2.1 規則字符在java.util.regex Pattern類中

2.2 常見符號

2.2.1 字符

符號 說明
X 字符X
\\ 反斜線
\t 制表符 ('\u0009')
\n 回車
\r 換行
\f 換頁符 ('\u000C')
\a 報警 (bell) 符 ('\u0007')

2.2.2 字符類

符號 說明
[abc] a、b或c
[^abc] 任何字符,除了a、b或c
[a-zA-Z] a到z,或A到Z
[0-9] 0到9的字符
[a-d[m-p]] a到 d或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e或 f(交集)
[a-z&&[^bc]] a到 z,除了 b和 c:[ad-z](減去)
[a-z&&[^m-p]] a到 z,而非 m到 p:[a-lq-z](減去)

2.2.3 預定義字符

符號 說明
. 任何字符
\d 數字:[0-9]
\D 非數字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 單詞字符:[a-zA-Z_0-9]
\W 非單詞字符:[^\w]

2.3 邊界匹配器

符號 說明
^ 行開頭
$ 行結尾
\b 單詞邊界
\B 非單詞邊界
\A 輸入的開頭
\G 上一個匹配的結尾
\Z 輸入的結尾,僅用于最后的結束符(如果有的話)
\z 輸入的結尾

2.3.1 Greedy數量詞

符號 說明
X? 0次或1次
X* 0次以上
X+ 1次以上
X{n} 恰好n次
X{n,} 至少n次
X{n,m} n-m次

2.3.2 組和捕獲

捕獲組可以通過從左到右計算其開括號來編號。例如,在表達式 ((A)(B(C)))中,存在四個這樣的組:

  • ((A)(B(C)))
  • \A
  • (B(C))
  • (C)

組零始終代表整個表達式。在替換中常用$匹配組的內容。

3. 正則表達式的應用

3.1 判斷功能

public  boolean matches(String regex):編譯給定正則表達式并嘗試將給定輸入與其匹配。

3.2 分割功能

 public  String[] split(String regex):根據指定的正則表達式分割字符串

3.3 替換功能

public  String replaceAll(String regex,String replacement)

使用給定的 replacement 替換此字符串所有匹配給定的正則表達式的子字符串。

3.4 獲取功能

Pattern和Matcher類的使用

package cn.itcast_05;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
 * 獲取功能
 *      Pattern和Matcher類的使用
 *      
 *      模式和匹配器的基本使用順序
 */
public class RegexDemo {
    public static void main(String[] args) {
        // 模式和匹配器的典型調用順序
        // 把正則表達式編譯成模式對象
        Pattern p = Pattern.compile("a*b");
        // 通過模式對象得到匹配器對象,這個時候需要的是被匹配的字符串
        Matcher m = p.matcher("aaaaab");
        // 調用匹配器對象的功能
        boolean b = m.matches();
        System.out.println(b);
        
        //這個是判斷功能,但是如果做判斷,這樣做就有點麻煩了,我們直接用字符串的方法做
        String s = "aaaaab";
        String regex = "a*b";
        boolean bb = s.matches(regex);
        System.out.println(bb);
    }
}

Pattern 匹配模式

方法聲明 功能描述
compile() 把正則表達式編譯成匹配模式
matcher() 根據匹配模式去匹配指定的字符串,得到匹配器

Matcher 匹配器

方法聲明 功能描述
matches() 匹配字符串
find() 查找有沒有滿足條件的子串
group() 獲取滿足條件的子串

3.4 注意事項

Pattern類為正則表達式的編譯表示形式。指定為字符串的正則表達式必須首先被編譯為此類的實例。然后,可將得到的模式用于創建Matcher對象,依照正則表達式,該對象可以與任意字符序列匹配。執行匹配所涉及的所有狀態都駐留在匹配器中,所以多個匹配器可以共享同一模式

4. 正則表達式的練習

4.1 判斷功能:校驗郵箱

package cn.itcast_02;
import java.util.Scanner;
/*
 * 校驗郵箱
 * 
 * 分析:
 *      A:鍵盤錄入郵箱
 *      B:定義郵箱的規則
 *          1517806580@qq.com
 *          liuyi@163.com
 *          linqingxia@126.com
 *          fengqingyang@sina.com.cn
 *          fqy@itcast.cn
 *      C:調用功能,判斷即可
 *      D:輸出結果
 */
public class RegexTest {
    public static void main(String[] args) {
        //鍵盤錄入郵箱
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入郵箱:");
        String email = sc.nextLine();
        
        //定義郵箱的規則
        //String regex = "[a-zA-Z_0-9]+@[a-zA-Z_0-9]{2,6}(\\.[a-zA-Z_0-9]{2,3})+";
        String regex = "\\w+@\\w{2,6}(\\.\\w{2,3})+";
        
        //調用功能,判斷即可
        boolean flag = email.matches(regex);
        
        //輸出結果
        System.out.println("flag:"+flag);
    }
}

4.2 分割功能

代碼示例:我有如下一個字符串:”91 27 46 3850”,請寫代碼實現最終輸出結果是:”27 3846 50 91”

package cn.itcast_03;
import java.util.Arrays;
/*
 * 我有如下一個字符串:"91 27 46 38 50"
 * 請寫代碼實現最終輸出結果是:"27 38 46 50 91"
 * 
 * 分析:
 *      A:定義一個字符串
 *      B:把字符串進行分割,得到一個字符串數組
 *      C:把字符串數組變換成int數組
 *      D:對int數組排序
 *      E:把排序后的int數組在組裝成一個字符串
 *      F:輸出字符串
 */
public class RegexTest {
    public static void main(String[] args) {
        // 定義一個字符串
        String s = "91 27 46 38 50";

        // 把字符串進行分割,得到一個字符串數組
        String[] strArray = s.split(" ");

        // 把字符串數組變換成int數組
        int[] arr = new int[strArray.length];

        for (int x = 0; x < arr.length; x++) {
            arr[x] = Integer.parseInt(strArray[x]);
        }

        // 對int數組排序
        Arrays.sort(arr);

        // 把排序后的int數組在組裝成一個字符串
        StringBuilder sb = new StringBuilder();
        for (int x = 0; x < arr.length; x++) {
            sb.append(arr[x]).append(" ");
        }
        //轉化為字符串
        String result = sb.toString().trim();
        
        //輸出字符串
        System.out.println("result:"+result);
    }
}

4.3 替換功能:論壇中不能出現數字字符,用替換*

package cn.itcast_04;
/*
 * 替換功能
 *      String類的public String replaceAll(String regex,String replacement)
 *      使用給定的 replacement 替換此字符串所有匹配給定的正則表達式的子字符串。 
 */
public class RegexDemo {
    public static void main(String[] args) {
        // 定義一個字符串
        String s = "helloqq12345worldkh622112345678java";

        // 我要去除所有的數字,用*給替換掉
        // String regex = "\\d+";
        // String regex = "\\d";
        //String ss = "*";
        
        
        // 直接把數字干掉
        String regex = "\\d+";
        String ss = "";

        String result = s.replaceAll(regex, ss);
        System.out.println(result);
    }
}

4.4 獲取功能:獲取由三個字符組成的單詞

package cn.itcast_05;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
 * 獲取功能:
 * 獲取下面這個字符串中由三個字符組成的單詞
 * da jia ting wo shuo,jin tian yao xia yu,bu shang wan zi xi,gao xing bu?
 */
public class RegexDemo2 {
    public static void main(String[] args) {
        // 定義字符串
        String s = "da jia ting wo shuo,jin tian yao xia yu,bu shang wan zi xi,gao xing bu?";
        // 規則
        String regex = "\\b\\w{3}\\b";

        // 把規則編譯成模式對象
        Pattern p = Pattern.compile(regex);
        // 通過模式對象得到匹配器對象
        Matcher m = p.matcher(s);
        // 調用匹配器對象的功能
        // 通過find方法就是查找有沒有滿足條件的子串
        // public boolean find()
        // boolean flag = m.find();
        // System.out.println(flag);
        // // 如何得到值呢?
        // // public String group()
        // String ss = m.group();
        // System.out.println(ss);
        //
        // // 再來一次
        // flag = m.find();
        // System.out.println(flag);
        // ss = m.group();
        // System.out.println(ss);

        while (m.find()) {
            System.out.println(m.group());
        }

        // 注意:一定要先find(),然后才能group()
        // IllegalStateException: No match found
        // String ss = m.group();
        // System.out.println(ss);
    }
}

5. 正則表達式工具類

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 正則工具類 提供驗證郵箱、手機號、電話號碼、身份證號碼、數字等方法
 */
public final class RegexUtils {

    /**
     * 驗證Email
     * 
     * @param email
     *            email地址,格式:zhangsan@sina.com,zhangsan@xxx.com.cn,xxx代表郵件服務商
     * @return 驗證成功返回true,驗證失敗返回false ^ :匹配輸入的開始位置。 \:將下一個字符標記為特殊字符或字面值。
     *         :匹配前一個字符零次或幾次。 + :匹配前一個字符一次或多次。 (pattern) 與模式匹配并記住匹配。 x|y:匹配 x 或
     *         y。 [a-z] :表示某個范圍內的字符。與指定區間內的任何字符匹配。 \w :與任何單詞字符匹配,包括下劃線。
     * 
     *         {n,m} 最少匹配 n 次且最多匹配 m 次 $ :匹配輸入的結尾。
     */
    public static boolean checkEmail(String email) {
        String regex = "^(\\w)+(\\.\\w+)*@(\\w)+((\\.\\w{2,3}){1,3})$";
        return Pattern.matches(regex, email);
    }

    /**
     * 驗證身份證號碼
     * 
     * @param idCard
     *            居民身份證號碼15位或18位,最后一位可能是數字或字母
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkIdCard(String idCard) {
        String regex = "[1-9]\\d{13,16}[a-zA-Z0-9]{1}";
        return Pattern.matches(regex, idCard);
    }

    /**
     * 驗證手機號碼(支持國際格式,+86135xxxx...(中國內地),+00852137xxxx...(中國香港))
     * 
     * @param mobile
     *            移動、聯通、電信運營商的號碼段
     *            <p>
     *            移動的號段:134(0-8)、135、136、137、138、139、147(預計用于TD上網卡)
     *            、150、151、152、157(TD專用)、158、159、187(未啟用)、188(TD專用)
     *            </p>
     *            <p>
     *            聯通的號段:130、131、132、155、156(世界風專用)、185(未啟用)、186(3g)
     *            </p>
     *            <p>
     *            電信的號段:133、153、180(未啟用)、189
     *            </p>
     *            <p>
     *            虛擬運營商的號段:170
     *            </p>
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkMobile(String mobile) {
        String regex = "(\\+\\d+)?1[34578]\\d{9}$";
        return Pattern.matches(regex, mobile);
    }

    /**
     * 驗證固定電話號碼
     * 
     * @param phone
     *            電話號碼,格式:國家(地區)電話代碼 + 區號(城市代碼) + 電話號碼,如:+8602085588447
     *            <p>
     *            <b>國家(地區) 代碼 :</b>標識電話號碼的國家(地區)的標準國家(地區)代碼。它包含從 0 到 9
     *            的一位或多位數字, 數字之后是空格分隔的國家(地區)代碼。
     *            </p>
     *            <p>
     *            <b>區號(城市代碼):</b>這可能包含一個或多個從 0 到 9 的數字,地區或城市代碼放在圓括號——
     *            對不使用地區或城市代碼的國家(地區),則省略該組件。
     *            </p>
     *            <p>
     *            <b>電話號碼:</b>這包含從 0 到 9 的一個或多個數字
     *            </p>
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkPhone(String phone) {
        // String regex = "(\\+\\d+)?(\\d{3,4}\\-?)?\\d{7,8}$";
        String regex = "^1\\d{10}$";
        return Pattern.matches(regex, phone);
    }

    /**
     * 驗證整數(正整數和負整數)
     * 
     * @param digit
     *            一位或多位0-9之間的整數
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkDigit(String digit) {
        String regex = "\\-?[1-9]\\d+";
        return Pattern.matches(regex, digit);
    }

    /**
     * 驗證整數和浮點數(正負整數和正負浮點數)
     * 
     * @param decimals
     *            一位或多位0-9之間的浮點數,如:1.23,233.30
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkDecimals(String decimals) {
        String regex = "\\-?[1-9]\\d+(\\.\\d+)?";
        return Pattern.matches(regex, decimals);
    }

    /**
     * 驗證空白字符
     * 
     * @param blankSpace
     *            空白字符,包括:空格、\t、\n、\r、\f、\x0B
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkBlankSpace(String blankSpace) {
        String regex = "\\s+";
        return Pattern.matches(regex, blankSpace);
    }

    /**
     * 驗證中文
     * 
     * @param chinese
     *            中文字符
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkChinese(String chinese) {
        String regex = "^[\u4E00-\u9FA5]+$";
        return Pattern.matches(regex, chinese);
    }

    /**
     * 驗證日期(年月日)
     * 
     * @param birthday
     *            日期,格式:1992-09-03,或1992.09.03
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkBirthday(String birthday) {
        String regex = "[1-9]{4}([-./])\\d{1,2}\\1\\d{1,2}";
        return Pattern.matches(regex, birthday);
    }

    /**
     * 驗證URL地址
     * 
     * @param url
     *            格式:http://blog.csdn.net:80/xyang81/article/details/7705960? 或
     *            http://www.csdn.net:80
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkURL(String url) {
        String regex = "(https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?";
        return Pattern.matches(regex, url);
    }

    /**
     * 匹配中國郵政編碼
     * 
     * @param postcode
     *            郵政編碼
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkPostcode(String postcode) {
        String regex = "[1-9]\\d{5}";
        return Pattern.matches(regex, postcode);
    }

    /**
     * 匹配IP地址(簡單匹配,格式,如:192.168.1.1,127.0.0.1,沒有匹配IP段的大小)
     * 
     * @param ipAddress
     *            IPv4標準地址
     * @return 驗證成功返回true,驗證失敗返回false
     */
    public static boolean checkIpAddress(String ipAddress) {
        String regex = "[1-9](\\d{1,2})?\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))";
        return Pattern.matches(regex, ipAddress);
    }

    public static boolean checkNickname(String nickname) {
        String regex = "^[a-zA-Z0-9\u4E00-\u9FA5_]+$";
        return Pattern.matches(regex, nickname);
    }
    

    public static boolean hasCrossSciptRiskInAddress(String str) {
        String regx = "[`~!@#$%^&*+=|{}':;',\\[\\].<>~!@#¥%……&*——+|{}【】‘;:”“’。,、?-]";
        if (str != null) {
            str = str.trim();
            Pattern p = Pattern.compile(regx, Pattern.CASE_INSENSITIVE);
            Matcher m = p.matcher(str);
            return m.find();
        }
        return false;
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 概述 正則表達式通常用于兩種功能:驗證和搜索/替換。用于驗證時,通常需要在前后分別加上^和$,以匹配整個待驗證字符...
    陳晨_Fly閱讀 632評論 1 5
  • 初衷:看了很多視頻、文章,最后卻通通忘記了,別人的知識依舊是別人的,自己卻什么都沒獲得。此系列文章旨在加深自己的印...
    DCbryant閱讀 4,059評論 0 20
  • 推薦幾個正則表達式編輯器 Debuggex :https://www.debuggex.com/ PyRegex:...
    木易林1閱讀 11,534評論 9 151
  • 幾個正則表達式編輯器 Debuggex :https://www.debuggex.com/ PyRegex:ht...
    沒技術的BUG開發攻城獅閱讀 4,615評論 0 23
  • 正則表達式到底是什么東西?字符是計算機軟件處理文字時最基本的單位,可能是字母,數字,標點符號,空格,換行符,漢字等...
    獅子挽歌閱讀 2,169評論 0 9