恭喜你,Get到一份 正則表達式 食用指南

先贊後看,養成習慣

前言

正則表達式

正則表達式: 定義一個搜索模式的字符串。java

正則表達式能夠用於搜索、編輯和操做文本。面試

正則對文本的分析或修改過程爲:首先正則表達式應用的是文本字符串(text/string),它會以定義的模式從左到右匹配文本,每一個源字符只匹配一次。正則表達式

Java中正則表達式的使用

字符串內置正則

在 Java 中有四個內置的運行正則表達式的方法,分別是 matches()split())replaceFirst()replaceAll()。注意 replace() 方法不支持正則表達式。segmentfault

方法 描述
s.matches("regex") 當僅且當正則匹配整個字符串時返回 true
s.split("regex") 按匹配的正則表達式切片字符串
s.replaceFirst("regex", "replacement") 替換首次匹配的字符串片斷
s.replaceAll("regex", "replacement") 替換全部匹配的字符

示例代碼學習

System.out.println("lby".matches("lby"));
            System.out.println("----------");

            String[] array = "l b y".split("\\s");
            for (String item : array) {
                System.out.println(item);
            }
            System.out.println("----------");

            System.out.println("l b y".replaceFirst("\\s", "-"));
            System.out.println("----------");

            System.out.println("l b y".replaceAll("\\s", "-"));

運行結果測試

true
----------
l
b
y
----------
l-b y
----------
l-b-y

regex包

java.util.regex 包主要包括如下三個類:url

  1. Pattern 類spa

    pattern 對象是一個正則表達式的編譯表示。Pattern 類沒有公共構造方法。要建立一個 Pattern 對象,你必須首先調用其公共靜態編譯方法,它返回一個 Pattern 對象。該方法接受一個正則表達式做爲它的第一個參數。
  2. Matcher 類3d

    Matcher 對象是對輸入字符串進行解釋和匹配操做的引擎。與Pattern 類同樣,Matcher 也沒有公共構造方法。你須要調用 Pattern 對象的 matcher 方法來得到一個 Matcher 對象。
  3. PatternSyntaxExceptioncode

    PatternSyntaxException 是一個非強制異常類,它表示一個正則表達式模式中的語法錯誤。

Java 中regex 包使用正則表達式基本步驟

  1. 經過正則表達式建立模式對象 Pattern。
  2. 經過模式對象 Pattern,根據指定字符串建立匹配對象 Matcher。
  3. 經過匹配對象 Matcher,根據正則表達式操做字符串。

例如

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

public class TestRegex {
    public static void main(String[] args) {
        //定義一個字符串
        String text = "Hello Regex!";
        //建立一個Pattern對象  能夠認爲根據正則表達式獲取一個對應的對象
        Pattern pattern = Pattern.compile("\\w+");
        // Java 中忽略大小寫,有兩種寫法:
        // Pattern pattern = Pattern.compile("\\w+", Pattern.CASE_INSENSITIVE);
        // Pattern pattern = Pattern.compile("(?i)\\w+"); // 推薦寫法
        Matcher matcher = pattern.matcher(text);
        // 遍例全部匹配的序列
        while (matcher.find()) {
            System.out.print("Start index: " + matcher.start());
            System.out.print(" End index: " + matcher.end() + " ");
            System.out.println(matcher.group());
        }
        
    }
}

運行的結果爲:

Start index: 0 End index: 5 Hello

Start index: 6 End index: 11 Regex、

以上代碼看不懂沒有關係,提早感覺一下正則的神奇,接下來咱們學習一下正則表達式的的語法。

正則表達式的語法

常見匹配符號

正則表達式 描述
. 匹配全部單個字符,除了換行符(Linux 中換行是 \n,Windows 中換行是 \r\n
^regex 正則必須匹配字符串開頭
regex$ 正則必須匹配字符串結尾
[abc] 複選集定義,匹配字母 a 或 b 或 c
[abc][vz] 複選集定義,匹配字母 a 或 b 或 c,後面跟着 v 或 z
[^abc] 當插入符 ^ 在中括號中以第一個字符開始顯示,則表示否認模式。此模式匹配全部字符,除了 a 或 b 或 c
[a-d1-7] 範圍匹配,匹配字母 a 到 d 和數字從 1 到 7 之間,但不匹配 d1
XZ 匹配 X 後直接跟着 Z
X\ Z 匹配 X 或 Z

元字符

元字符是一個預約義的字符。

正則表達式 描述
\d 匹配一個數字,是 [0-9] 的簡寫
\D 匹配一個非數字,是 [^0-9] 的簡寫
\s 匹配一個空格,是 [ \t\n\x0b\r\f] 的簡寫
\S 匹配一個非空格
\w 匹配一個單詞字符(大小寫字母、數字、下劃線),是 [a-zA-Z_0-9] 的簡寫
\W 匹配一個非單詞字符(除了大小寫字母、數字、下劃線以外的字符),等同於 [^\w]

限定符

限定符定義了一個元素能夠發生的頻率。

正則表達式 描述 舉例
* 匹配 >=0 個,是 {0,} 的簡寫 X* 表示匹配零個或多個字母 X,.*表示匹配任何字符串
+ 匹配 >=1 個,是 {1,} 的簡寫 X+ 表示匹配一個或多個字母 X
? 匹配 1 個或 0 個,是 {0,1} 的簡寫 X? 表示匹配 0 個或 1 個字母 X
{X} 只匹配 X 個字符 \d{3} 表示匹配 3 個數字,.{10}表示匹配任何長度是 10 的字符串
{X,Y} 匹配 >=X 且 <=Y 個 \d{1,4} 表示匹配至少 1 個最多 4 個數字
*? 若是 ? 是限定符 *+?{} 後面的第一個字符,那麼表示非貪婪模式(儘量少的匹配字符),而不是默認的貪婪模式

分組和反向引用

小括號 () 能夠達到對正則表達式進行分組的效果。

模式分組後會在正則表達式中建立反向引用。反向引用會保存匹配模式分組的字符串片段,這使得咱們能夠獲取並使用這個字符串片段。

在以正則表達式替換字符串的語法中,是經過 $ 來引用分組的反向引用,$0 是匹配完整模式的字符串(注意在 JavaScript 中是用 $& 表示);$1 是第一個分組的反向引用;$2 是第二個分組的反向引用,以此類推。

示例:

package com.baizhi.test;

public class RegexTest {

    public static void main(String[] args) {
        // 去除單詞與 , 和 . 之間的空格
        String Str = "Hello , World .";
        String pattern = "(\\w)(\\s+)([.,])";
        // $0 匹配 `(\w)(\s+)([.,])` 結果爲 `o空格,` 和 `d空格.`
        // $1 匹配 `(\w)` 結果爲 `o` 和 `d`
        // $2 匹配 `(\s+)` 結果爲 `空格` 和 `空格`
        // $3 匹配 `([.,])` 結果爲 `,` 和 `.`
        System.out.println(Str.replaceAll(pattern, "$1$3")); // Hello, World.
    }
}

上面的例子中,咱們使用了 [.] 來匹配普通字符 . 而不須要使用 [\\.]。由於正則對於 [] 中的 .,會自動處理爲 [\.],即普通字符 . 進行匹配。

否認先行斷言(Negative lookahead)

咱們能夠建立否認先行斷言模式的匹配,即某個字符串後面不包含另外一個字符串的匹配模式。

否認先行斷言模式經過 (?!pattern) 定義。好比,咱們匹配後面不是跟着 "b" 的 "a":

a(?!b)

指定正則表達式的模式

能夠在正則的開頭指定模式修飾符。

  • (?i) 使正則忽略大小寫。
  • (?s) 表示單行模式("single line mode")使正則的 . 匹配全部字符,包括換行符。
  • (?m) 表示多行模式("multi-line mode"),使正則的 ^$ 匹配字符串中每行的開始和結束。

Java 中的反斜槓

反斜槓 \ 在 Java 中表示轉義字符,這意味着 \ 在 Java 擁有預約義的含義。

這裏例舉兩個特別重要的用法:

  • 在匹配 .{[(?$^* 這些特殊字符時,須要在前面加上 \\,好比匹配 . 時,Java 中要寫爲 \\.,但對於正則表達式來講就是 \.
  • 在匹配 \ 時,Java 中要寫爲 \\\\,但對於正則表達式來講就是 \\

注意:Java 中的正則表達式字符串有兩層含義,首先 Java 字符串轉義出符合正則表達式語法的字符串,而後再由轉義後的正則表達式進行模式匹配。

正則表達式常見應用示例

中文的匹配

[\u4e00-\u9fa5]+ 表明匹配中文字。

public static void test3(){
        String str = "這裏有個新手易範的錯誤,就是正angongsi";
        Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }

數字範圍的匹配

好比,匹配 1990 到 2017。

注意:這裏有個新手易範的錯誤,就是正則 [1990-2017],實際這個正則只匹配 01279 中的任一個字符。

正則表達式匹配數字範圍時,首先要肯定最大值與最小值,最後寫中間值。

正確的匹配方式:

public static void test4(){
        String str = "1990\n2010\n2017\nsdfgadfggadfgdfgdfgafdgasfdga\n1998";
        // 這裏應用了 (?m) 的多行匹配模式,只爲方便咱們測試輸出
        // "^1990$|^199[1-9]$|^20[0-1][0-6]$|^2017$" 爲判斷 1990-2017 正確的正則表達式
        Pattern pattern = Pattern.compile("(?m)^1990$|^199[1-9]$|^20[0-1][0-6]$|^2017$");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }

img 標籤的匹配

好比,獲取圖片文件內容,這裏咱們考慮了一些不規範的 img 標籤寫法:

public static void test5(){
         String str = "<img  src='aaa.jpg' /><img src=bbb.png/><img src=\"ccc.png\"/>" +
                    "<img src='ddd.exe'/><img src='eee.jpn'/>";
            // 這裏咱們考慮了一些不規範的 img 標籤寫法,好比:空格、引號
            Pattern pattern = Pattern.compile("<img\\s+src=(?:['\"])?(?<src>\\w+.(jpg|png))(?:['\"])?\\s*/>");
            Matcher matcher = pattern.matcher(str);
            while (matcher.find()) {
                System.out.println(matcher.group("src"));
            }
    }

郵箱匹配

郵箱匹配的正則的寫法有不少,這裏給出一種參考的寫法。

合法E-mail地址:

  1. 必須包含一個而且只有一個符號「@」
  2. 第一個字符不得是「@」或者「.」
  3. 不容許出現「@.」或者.@
  4. 結尾不得是字符「@」或者「.」
  5. 容許「@」前的字符中出現「+」
  6. 不容許「+」在最前面,或者「+@」

等等

示例代碼

public static void test6(){
         String check = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";  
         Pattern regex = Pattern.compile(check);  
         Matcher matcher = regex.matcher("dffdfdf@qq.com");  
         boolean isMatched = matcher.matches();  
         System.out.println(isMatched); 
    }

手機號匹配

public static void test7(){
        String check = "^((13[0-9])|(15[^4])|(18[0-9])|(17[0-9])|(147))\\d{8}$"; 
         Pattern regex = Pattern.compile(check); 
         Matcher matcher = regex.matcher("18638693953"); 
         boolean isMatched = matcher.matches(); 
         System.out.println(isMatched); 
    }

url匹配

public static void test8(){
        String url = "http://www.lubingyang.com/";
        String regex = "(https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?";
        boolean isMatched = Pattern.matches(regex, url);
        System.out.println(isMatched);
    }

求點贊,求關注,求轉發

歡迎關注本人公衆號:鹿老師的Java筆記,將在長期更新Java技術圖文教程和視頻教程,Java學習經驗,Java面試經驗以及Java實戰開發經驗。