先贊後看,養成習慣java
正則表達式: 定義一個搜索模式的字符串。面試
正則表達式能夠用於搜索、編輯和操做文本。正則表達式
正則對文本的分析或修改過程爲:首先正則表達式應用的是文本字符串(text/string),它會以定義的模式從左到右匹配文本,每一個源字符只匹配一次。學習
在 Java 中有四個內置的運行正則表達式的方法,分別是 matches()
、split())
、replaceFirst()
、replaceAll()
。注意 replace()
方法不支持正則表達式。測試
方法 | 描述 |
---|---|
s.matches("regex") |
當僅且當正則匹配整個字符串時返回 true |
s.split("regex") |
按匹配的正則表達式切片字符串 |
s.replaceFirst("regex", "replacement") |
替換首次匹配的字符串片斷 |
s.replaceAll("regex", "replacement") |
替換全部匹配的字符 |
示例代碼url
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", "-"));
運行結果code
true ---------- l b y ---------- l-b y ---------- l-b-y
java.util.regex 包主要包括如下三個類:視頻
Pattern 類對象
pattern 對象是一個正則表達式的編譯表示。Pattern 類沒有公共構造方法。要建立一個 Pattern 對象,你必須首先調用其公共靜態編譯方法,它返回一個 Pattern 對象。該方法接受一個正則表達式做爲它的第一個參數。blog
Matcher 類
Matcher 對象是對輸入字符串進行解釋和匹配操做的引擎。與Pattern 類同樣,Matcher 也沒有公共構造方法。你須要調用 Pattern 對象的 matcher 方法來得到一個 Matcher 對象。
PatternSyntaxException
PatternSyntaxException 是一個非強制異常類,它表示一個正則表達式模式中的語法錯誤。
Java 中regex 包使用正則表達式基本步驟
經過正則表達式建立模式對象 Pattern。
經過模式對象 Pattern,根據指定字符串建立匹配對象 Matcher。
經過匹配對象 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. } }
上面的例子中,咱們使用了 [.]
來匹配普通字符 .
而不須要使用 [\\.]
。由於正則對於 []
中的 .
,會自動處理爲 [\.]
,即普通字符 .
進行匹配。
咱們能夠建立否認先行斷言模式的匹配,即某個字符串後面不包含另外一個字符串的匹配模式。
否認先行斷言模式經過 (?!pattern)
定義。好比,咱們匹配後面不是跟着 "b" 的 "a":
a(?!b)
能夠在正則的開頭指定模式修飾符。
(?i)
使正則忽略大小寫。(?s)
表示單行模式("single line mode")使正則的 .
匹配全部字符,包括換行符。(?m)
表示多行模式("multi-line mode"),使正則的 ^
和 $
匹配字符串中每行的開始和結束。反斜槓 \
在 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]
,實際這個正則只匹配 0
或 1
或 2
或 7
或 9
中的任一個字符。
正則表達式匹配數字範圍時,首先要肯定最大值與最小值,最後寫中間值。
正確的匹配方式:
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 標籤寫法:
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地址:
- 必須包含一個而且只有一個符號「@」
- 第一個字符不得是「@」或者「.」
- 不容許出現「@.」或者.@
- 結尾不得是字符「@」或者「.」
- 容許「@」前的字符中出現「+」
- 不容許「+」在最前面,或者「+@」
等等
示例代碼
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); }
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實戰開發經驗。