摘要:正則表達式可以用于搜索編輯和操作文本。模式分組后會在正則表達式中創建反向引用。使正則忽略大小寫。注意方法不支持正則表達式。第三步,通過匹配對象,根據正則表達式操作字符串。正則表達式匹配數字范圍時,首先要確定最大值與最小值,最后寫中間值。
版權聲明:本文由吳仙杰創作整理,轉載請注明出處:https://segmentfault.com/a/11900000091623061. 正則表達式 1.1 什么是正則表達式
正則表達式
: 定義一個搜索模式的字符串。
正則表達式可以用于搜索、編輯和操作文本。
正則對文本的分析或修改過程為:首先正則表達式應用的是文本字符串(text/string),它會以定義的模式從左到右匹配文本,每個源字符只匹配一次。
1.2 示例正則表達式 | 匹配 |
---|---|
this is text | 精確匹配字符串 "this is text" |
thiss+iss+text | 匹配單詞 "this" 后跟一個或多個空格字符,后跟詞 "is" 后跟一個或多個空格字符,后跟詞 "text" |
^d+(.d+)? | ^ 定義模式必須匹配字符串的開始,d+ 匹配一個或多個數字,? 表明小括號內的語句是可選的,. 匹配 ".",小括號表示分組。例如匹配:"5"、"1.5" 和 "2.21" |
正則表達式 | 描述 |
---|---|
. | 匹配所有單個字符,除了換行符(Linux 中換行是 ,Windows 中換行是 ) |
^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 | 匹配一個空格,是 [ x0b 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.wuxianjiezh.demo.regex; 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. } }
上面的例子中,我們使用了 [.] 來匹配普通字符 . 而不需要使用 [.]。因為正則對于 [] 中的 .,會自動處理為 [.],即普通字符 . 進行匹配。
2.4.1 僅分組但無反向引用當我們在小括號 () 內的模式開頭加入 ?:,那么表示這個模式僅分組,但不創建反向引用。
示例:
package com.wuxianjiezh.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexTest { public static void main(String[] args) { String str = "img.jpg"; // 分組且創建反向引用 Pattern pattern = Pattern.compile("(jpg|png)"); Matcher matcher = pattern.matcher(str); while (matcher.find()) { System.out.println(matcher.group()); System.out.println(matcher.group(1)); } } }
運行結果:
jpg jpg
若源碼改為:
package com.wuxianjiezh.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexTest { public static void main(String[] args) { String str = "img.jpg"; // 分組但不創建反向引用 Pattern pattern = Pattern.compile("(?:jpg|png)"); Matcher matcher = pattern.matcher(str); while (matcher.find()) { System.out.println(matcher.group()); System.out.println(matcher.group(1)); } } }
運行結果:
jpg Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 1 at java.util.regex.Matcher.group(Matcher.java:538) at com.wuxianjiezh.regex.RegexTest.main(RegexTest.java:15)2.4.2 分組的反向引用副本
Java 中可以在小括號中使用 ?
示例:
package com.wuxianjiezh.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexTest { public static void main(String[] args) { String str = "@wxj 你好啊"; Pattern pattern = Pattern.compile("@(?w+s)"); // 保存一個副本 Matcher matcher = pattern.matcher(str); while (matcher.find()) { System.out.println(matcher.group()); System.out.println(matcher.group(1)); System.out.println(matcher.group("first")); } } }
運行結果:
@wxj wxj wxj2.5 否定先行斷言(Negative lookahead)
我們可以創建否定先行斷言模式的匹配,即某個字符串后面不包含另一個字符串的匹配模式。
否定先行斷言模式通過 (?!pattern) 定義。比如,我們匹配后面不是跟著 "b" 的 "a":
a(?!b)2.6 指定正則表達式的模式
可以在正則的開頭指定模式修飾符。
(?i) 使正則忽略大小寫。
(?s) 表示單行模式("single line mode")使正則的 . 匹配所有字符,包括換行符。
(?m) 表示多行模式("multi-line mode"),使正則的 ^ 和 $ 匹配字符串中每行的開始和結束。
2.7 Java 中的反斜杠反斜杠 在 Java 中表示轉義字符,這意味著 在 Java 擁有預定義的含義。
這里例舉兩個特別重要的用法:
在匹配 . 或 { 或 [ 或 ( 或 ? 或 $ 或 ^ 或 * 這些特殊字符時,需要在前面加上 ,比如匹配 . 時,Java 中要寫為 .,但對于正則表達式來說就是 .。
在匹配 時,Java 中要寫為 ,但對于正則表達式來說就是 。
注意:Java 中的正則表達式字符串有兩層含義,首先 Java 字符串轉義出符合正則表達式語法的字符串,然后再由轉義后的正則表達式進行模式匹配。
2.8 易錯點示例[jpg|png] 代表匹配 j 或 p 或 g 或 p 或 n 或 g 中的任意一個字符。
(jpg|png) 代表匹配 jpg 或 png。
3. 在字符串中使用正則表達式 3.1 內置的字符串正則處理方法在 Java 中有四個內置的運行正則表達式的方法,分別是 matches()、split())、replaceFirst()、replaceAll()。注意 replace() 方法不支持正則表達式。
方法 | 描述 |
---|---|
s.matches("regex") | 當僅且當正則匹配整個字符串時返回 true |
s.split("regex") | 按匹配的正則表達式切片字符串 |
s.replaceFirst("regex", "replacement") | 替換首次匹配的字符串片段 |
s.replaceAll("regex", "replacement") | 替換所有匹配的字符 |
示例代碼:
package com.wuxianjiezh.regex; public class RegexTest { public static void main(String[] args) { System.out.println("wxj".matches("wxj")); System.out.println("----------"); String[] array = "w x j".split("s"); for (String item : array) { System.out.println(item); } System.out.println("----------"); System.out.println("w x j".replaceFirst("s", "-")); System.out.println("----------"); System.out.println("w x j".replaceAll("s", "-")); } }
運行結果:
true ---------- w x j ---------- w-x j ---------- w-x-j4. 模式和匹配
Java 中使用正則表達式需要用到兩個類,分別為 java.util.regex.Pattern 和 java.util.regex.Matcher。
第一步,通過正則表達式創建模式對象 Pattern。
第二步,通過模式對象 Pattern,根據指定字符串創建匹配對象 Matcher。
第三步,通過匹配對象 Matcher,根據正則表達式操作字符串。
來個例子,加深理解:
package com.wuxianjiezh.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexTest { public static void main(String[] args) { String text = "Hello Regex!"; 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()); } // 創建第兩個模式,將空格替換為 tab Pattern replace = Pattern.compile("s+"); Matcher matcher2 = replace.matcher(text); System.out.println(matcher2.replaceAll(" ")); } }
運行結果:
Start index: 0 End index: 5 Hello Start index: 6 End index: 11 Regex Hello Regex!5. 若干個常用例子 5.1 中文的匹配
[u4e00-u9fa5]+ 代表匹配中文字。
package com.wuxianjiezh.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexTest { public static void main(String[] args) { String str = "閑人到人間"; Pattern pattern = Pattern.compile("[u4e00-u9fa5]+"); Matcher matcher = pattern.matcher(str); while (matcher.find()) { System.out.println(matcher.group()); } } }
運行結果:
閑人到人間5.2 數字范圍的匹配
比如,匹配 1990 到 2017。
注意:這里有個新手易范的錯誤,就是正則 [1990-2017],實際這個正則只匹配 0 或 1 或 2 或 7 或 9 中的任一個字符。
正則表達式匹配數字范圍時,首先要確定最大值與最小值,最后寫中間值。
正確的匹配方式:
package com.wuxianjiezh.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexTest { public static void main(String[] args) { String str = "1990 2010 2017"; // 這里應用了 (?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()); } } }
運行結果:
1990 2010 20175.3 img 標簽的匹配
比如,獲取圖片文件內容,這里我們考慮了一些不規范的 img 標簽寫法:
package com.wuxianjiezh.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexTest { public static void main(String[] args) { String str = "" + ""; // 這里我們考慮了一些不規范的 img 標簽寫法,比如:空格、引號 Pattern pattern = Pattern.compile(""); Matcher matcher = pattern.matcher(str); while (matcher.find()) { System.out.println(matcher.group("src")); } } }
運行結果:
aaa.jpg bbb.png ccc.png5.4 貪婪與非貪婪模式的匹配
比如,獲取 div 標簽中的文本內容:
package com.wuxianjiezh.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexTest { public static void main(String[] args) { String str = "文章標題發布時間"; // 貪婪模式 Pattern pattern = Pattern.compile("(?"); Matcher matcher = pattern.matcher(str); while (matcher.find()) { System.out.println(matcher.group("title")); } System.out.println("--------------"); // 非貪婪模式 pattern = Pattern.compile(".+) (?"); matcher = pattern.matcher(str); while (matcher.find()) { System.out.println(matcher.group("title")); } } }.+?)
運行結果:
文章標題
JavaScript、Python 等的在線表達式工具:https://regex101.com/
Java 在線表達式工具:http://www.regexplanet.com/advanced/java/index.html
7. 參考Java Regex - Tutorial
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69899.html
摘要:屬性里的字符串類似于數組,都是一個一個字符拼湊在一起組成的,因此可以用屬性取得字符串的長度字符串常用的一些方法返回字符串的第個字符,如果不在之間,則返回一個空字符串。如果匹配成功,則返回正則表達式在字符串中首次匹配項的索引否則,返回。 字符串 字符串就是一個或多個排列在一起的字符,放在單引號或雙引號之中。 abc abc length屬性js里的字符串類似于數組,都是一個一個字...
摘要:當活動線程核心線程非核心線程達到這個數值后,后續任務將會根據來進行拒絕策略處理。線程池工作原則當線程池中線程數量小于則創建線程,并處理請求。當線程池中的數量等于最大線程數時默默丟棄不能執行的新加任務,不報任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點記錄以及采用的解決方案 深入分析 java 線程池的實現原理 在這篇文章中,作者有條不紊的將 ja...
摘要:直接使用正則表達式對輸入的字符串進行匹配,匹配成功則返回使用正則表示式,進行字符串分割進行匹配操作,如果匹配成功,這三個方法都會返回其中,是在源字符串中找出和正則表達式匹配的字符串。 概念 正則表達式 在閱讀本文前,你應該已經了解了正則表達式的基本概念以及如何書寫正則表達式。如果對正則表達式不是太了解,或者想更深入地了解正則表示式,請點擊這里。 捕獲組 捕獲組能夠讓我們方便地從正則表達...
摘要:非貪婪模式盡可能少的匹配所搜索的字符串,而默認的貪婪模式則盡可能多的匹配所搜索的字符串。 導讀 你有沒有在搜索文本的時候絞盡腦汁, 試了一個又一個表達式, 還是不行. 你有沒有在表單驗證的時候, 只是做做樣子(只要不為空就好), 然后燒香拜佛, 虔誠祈禱, 千萬不要出錯. 你有沒有在使用sed 和 grep 命令的時候, 感覺莫名其妙, 明明應該支持的元字符, 卻就是匹配不到. 甚至,...
用Jmeter做接口測試只需要掌握幾個核心功能就可以了。 并不一定要把它所有的功能都掌握,先掌握核心功能入行,然后再根據工作需要和職業規劃來學習更多的內容。這篇文章在前面接口測試框架(測試計劃--->線程組--->請求--->查看結果樹)的前提下,來介紹必須要掌握的幾個核心功能,力求用最短的時間取得最大的成果。 在前面的文章中我提到,用Jmeter做接口測試的核心是單接口測試的參數化和關聯接口測試...
閱讀 1177·2021-11-23 10:10
閱讀 1499·2021-09-30 09:47
閱讀 887·2021-09-27 14:02
閱讀 2967·2019-08-30 15:45
閱讀 3020·2019-08-30 14:11
閱讀 3610·2019-08-29 14:05
閱讀 1820·2019-08-29 13:51
閱讀 2206·2019-08-29 11:33