天天看點

有必要了解的正規表達式

1、簡介

正規表達式(regular expression)描述了一種字元串比對的模式(pattern),可以用來檢查一個串是否含有某種子串、将比對的子串替換或者從某個串中取出符合某個條件的子串等。學習正規表達式很大程度上就是學習正規表達式的文法規則。

文本的複雜處理 一種強大而靈活的文本處理工具: 大部分程式設計語言 、 資料庫、文本編輯器、開發環境都支援正規表達式
2、基本文法

2.1、普通字元

字母、數字、漢字、下劃線、以及沒有特殊定義的标點符号,都是“普通字元”。表達式中的普通字元,在比對一個字元串的時候,比對與之相同的一個字元。 簡單的轉義字元
\n 代表換行符
\t 制表符
\ 代表\本身
^ ,$,.,(, ) , {, } , ? , + , * , 比對這些字元本身标準字元集合

2.2、标準字元集合

能夠與 ‘多種字元’ 比對的表達式 注意區分大小寫,大寫是相反的意思
\d 任意一個數字,0~9 中的任意一個
\D 除了數字以外的任一字元
\w 任意一個字母或數字或下劃線,也就是 A~Z,a~z,0~9,_ 中任意一個
\W 除了字母、數字和下劃線外的任一一個字元
\s 包括空格、制表符、換行符等空白字元的其中任意一個
\S 除了空格,制表符和換行符等空白字元外的任一個字元
. 小數點可以比對任意一個字元(除了換行符);如果要比對包括“\n”在内的所有字元,一般用[\s\S]

2.3、自定義字元集合

[ ]方括号比對方式,能夠比對方括号中任意一個字元
[ab5@] 比對 "a" 或 "b" 或 "5" 或 "@"
[^ abc] 比對 "a","b","c" 之外的任意一個字元
[f-k] 比對 "f"~"k" 之間的任意一個字母
[^A-F0-3] 比對 "A"~"F","0"~"3" 之外的任意一個字元
  • 正規表達式的特殊符号,被包含到中括号中,則失去特殊意義,除了^,-之外。
  • 标準字元集合,除小數點外,如果被包含于中括号,自定義字元集合将包含該集合。比如: [\d.-+]将比對:數字、小數點、+、-

2.4、量詞(Quantifier)

修飾比對次數的特殊符号:
{n} 表達式重複n次
{m,n} 表達式至少重複m次,最多重複n次
{m,} 表達式至少重複m次
? 比對表達式0次或者1次,相當于 {0,1}
+ 表達式至少出現1次,相當于 {1,}
* 表達式不出現或出現任意次,相當于 {0,}
  • 比對次數中的貪婪模式(比對字元越多越好,預設!)
  • 比對次數中的非貪婪模式(比對字元越少越好,修飾比對次數的特殊符号後再加上一個 "?" 号)
    • 比如,這裡比對的是:至少兩個數字,如果比對到則不比對 3、4等數字個數組合

      \d{2,6}?

  • 字元邊界: (本組标記比對的不是字元而是位置,符合某種條件的位置)
^ 與字元串開始的地方比對
$ 與字元串結束的地方比對
\b 比對一個單詞邊界

\b

比對這樣一個位置:前面的字元和後面的字元不全是

\w

正規表達式的比對模式
  • IGNORECASE 忽略大小寫模式
    • 比對時忽略大小寫。
    • 預設情況下,正規表達式是要區分大小寫的。
  • SINGLELINE 單行模式
    • 整個文本看作一個字元串,隻有一個開頭,一個結尾。
    • 使小數點 "." 可以比對包含換行符(\n)在内的任意字元。
  • MULTILINE 多行模式
    • 每行都是一個字元串,都有開頭和結尾。
    • 在指定了 MULTILINE 之後,如果需要僅比對字元串開始和結束位置,可以使用 \A 和 \Z

2.5、選擇符和分組

表達式 作用
豎線 分支結構 左右兩邊表達式之間 "或" 關系,比對左邊或者右邊
( )捕獲組 (1). 在被修飾比對次數的時候,括号中的表達式可以作為整體被修飾 (2). 取比對結果的時候,括号中的表達式比對到的内容可以被單獨得到 (3). 每一對括号會配置設定一個編号,使用()的捕獲根據左括号的順序從 1開始自動編号。捕獲元素編号為零的第一個捕獲是由整個正規表達式模式比對的文本
(?:Expression)非捕獲組 一些表達式中,不得不使用( ),但又不需要儲存( )中子表達式比對的内容,這時可以用非捕獲組來抵消使用( )帶來的副作用。

2.6、反向引用(\nnn)

  1. 每一對()會配置設定一個編号,使用 () 的捕獲根據左括号的順序從 1 開始自動編号。
  2. 通過反向引用,可以對分組已捕獲的字元串進行引用。

2.7、預搜尋(零寬斷言)

  1. 隻進行子表達式的比對,比對内容不計入最終的比對結果,是零寬度;
  2. 這個位置應該符合某個條件。判斷目前位置的前後字元,是否符合指定的條件,但不比對前後的字元。是對位置的比對;
  3. 正規表達式比對過程中,如果子表達式比對到的是字元内容,而非位置,并被儲存到最終的比對結果中,那麼就認為這個子表達式是占有字元的;如果子表達式比對的僅僅是位置,或者比對的内容并不儲存到最終的比對結果中,那麼就認為這個子表達式是零寬度的。占有字元還是零寬度,是針對比對的内容是否儲存到最終的比對結果中而言的。
(?=exp) 斷言自身出現的位置的後面能比對表達式exp
(?<=exp) 斷言自身出現的位置的前面能比對表達式exp
(?!exp) 斷言此位置的後面不能比對表達式exp
(?<!exp) 斷言此位置的前面不能比對表達式exp
3、練習

3.1、電話号碼驗證

  1. 電話号碼由數字和"-"構成
  2. 電話号碼為7到8位
  3. 如果電話号碼中包含有區号,那麼區号為三位或四位, 首位是0.
  4. 區号用"-"和其他部分隔開
  5. 行動電話号碼為11位
  6. 11位行動電話号碼的第一位和第二位為"13“,”15”,”18”
(0\d{2,3}-\d{7,8})|(1[3456789]\d{9})

3.2、電子郵件位址驗證

  1. 使用者名:字母、數字、中劃線、下劃線組成。
  2. @

  3. 網址:字母、數字組成。
  4. 小數點:.
  5. 組織域名:2-4位字母組成。
  6. 不區分大小寫
[\w-]+@[0-9a-zA-Z]+(.[a-zA-Z]{2,4}){1,2}
4、常用的正則式清單
比對中文字元 [\u4e00-\u9fa5]
比對空白行 \n\s*\r
比對HTML标記 <(\S*?)[^>]*>.*?</\1>
比對首尾空白字元 ^\s*
比對Email位址 \w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
比對網址URL [a-zA-z]+://[^\s]*
比對國内電話号碼 \d{3}-\d{8}
比對騰訊QQ号 [1-9][0-9]{4,}
比對中國郵政編碼 [1-9]\d{5}(?!\d)
比對身份證 \d{15}
比對ip位址 \d+\.\d+\.\d+\.\d+
5、Java中使用正規表達式

相關類位于:java.util.regex包下面

  • 類 Pattern:
    • 正規表達式的編譯表示形式。
    • Pattern p = Pattern.compile(r,int); //建立正規表達式,并啟用相應模式
  • 類 Matcher:
    • 通過解釋 Pattern 對 character sequence 執行比對操作的引擎
    • Matcher m = p.matcher(str); //比對str字元串

5.1、比對字元

package com.codesofun.regex;

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

/**
 * @ClassName Demo1
 * @Description TODO
 * @Author 小莫
 * @Date 2019/12/27 10:38
 * @Version 1.0
 **/
public class Demo1 {
    public static void main(String[] args) {
        String str = "dsadasdasd&&21312321";
        //表達式對象
        Pattern p = Pattern.compile("\\w+");
        //建立matcher對象
        Matcher matcher = p.matcher(str);
        //find() 該方法掃描輸入的序列,查找與該模式比對的下一個子序列
        System.out.println("===============");
        while (matcher.find()){
            System.out.println(matcher.group());
        }
        System.out.println("===============");

        boolean yesorno = matcher.matches();
        System.out.println(yesorno);

    }
}           

複制

package com.codesofun.regex;

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

/**
 * @ClassName Demo1
 * @Description TODO:正規表達式比對操作
 * @Author 小莫
 * @Date 2019/12/27 10:38
 * @Version 1.0
 **/
public class Demo2 {
    public static void main(String[] args) {
        String str = "aa32132**ssd312*sds122";
        //表達式對象
        Pattern p = Pattern.compile("([a-z]+)([0-9]+)");
        //建立matcher對象
        Matcher matcher = p.matcher(str);

        while (matcher.find()){
            //group() /group(0) 比對整個表達式的子字元串
            System.out.println(matcher.group() + "===>" + matcher.group(1) + "+" + matcher.group(2));
        }
    }
}           

複制

5.2、替換字元

package com.codesofun.regex;

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

/**
 * @ClassName Demo1
 * @Description TODO:正規表達式 替換操作
 * @Author 小莫
 * @Date 2019/12/27 10:38
 * @Version 1.0
 **/
public class Demo3 {
    public static void main(String[] args) {
        String str = "aa32132**ssd312*sds122";
        //表達式對象
        Pattern p = Pattern.compile("[0-9]");
        //建立matcher對象
        Matcher matcher = p.matcher(str);

        //替換
        String newStr = matcher.replaceAll("#");
        System.out.println(newStr);
    }
}           

複制

5.3、分割字元

package com.codesofun.regex;

import java.util.Arrays;

/**
 * @ClassName Demo1
 * @Description TODO:正規表達式 分割操作
 * @Author 小莫
 * @Date 2019/12/27 10:38
 * @Version 1.0
 **/
public class Demo4 {
    public static void main(String[] args) {
        String str = "aa32132ssd312sds122huhu";
        String[] strs = str.split("[\\d]+");
        System.out.println(Arrays.toString(strs));
    }
}           

複制

本文作者: AI碼真香

本文标題: 有必要了解的正規表達式

本文網址: https://www.xmlvhy.com/article/83.html

版權說明: 自由轉載-非商用-非衍生-保持署名 署名-非商業性使用4.0 國際 (CC BY-NC 4.0)