Java基礎-正則表達式(Regular Expression)語法規則簡介java
做者:尹正傑git
版權聲明:原創做品,謝絕轉載!不然將追究法律責任。正則表達式
一.正則表達式的概念app
正則表達式(Regular Expression,在代碼中常簡寫爲regex)是一個字符串,使用單個字符串來描述,用來定義匹配規則,匹配一系列符合某個句法規則的字符串。在開發中,正則表達式一般被用來檢索,替換那些符合某個規則的文本。ide
二.正則表達式經常使用的匹配規則測試
再看Java的API幫助文檔,在pattern類中有正則表達式的規則定義,正則表達式中明確區分大小寫字母。接下來咱們就來講一些Java經常使用的字符吧。spa
1>.字符"x"設計
含義:表明的是字符‘x’。code
例如:匹配規則爲「a」,那麼匹配的字符傳內容就是"a"。blog
2>.字符「\\」
含義:表明的反斜線字符‘\’(前面的"\"是轉義的做用,被轉的是「\」,後面的"\"被轉義爲了普通的斜線,失去了轉義的做用)。
例如:匹配規則爲「\\",那麼須要匹配的字符串內容就是「\」。
3>.字符"\t"
含義:製表符(前面的「\」是轉義的做用)。
例如:匹配規則爲「\t」,那麼對應的效果就是產生一個製表符的空間。
4>.字符「\n」
含義:換行符.
例如:匹配規則爲「\n」,那麼對應的效果就是換行,光標在原有位置的下一行。
5>.字符「\r」
含義:回車符。
例如:匹配規則爲「\r」,那麼對應的效果就是回車後的效果,光標來到下一行行首。
6>.字符類"[abc]"
含義:表明的是字符'a','b','c'。
例如:匹配規則爲「[abc]」,那麼須要匹配的內容就是字符a,或者字符b,或字符c的其中一個。
7>.字符類"[^abc]"
含義:表明的是除了a,b或c之外的任何字符。
例如:匹配規則爲「[^abc]」,那麼須要匹配的內容就是否是字符‘a’,或者不是字符'b',或不是字符‘c’的任意一個字符。
8>.字符類"[a-zA-Z]"
含義:帶包的是a到z或A到Z,兩頭的字母包括再內。
例如:匹配規則爲「[a-zA-Z]」,那麼須要匹配的是一個大寫或者小寫字母。
9>.字符類"[0-9]"
含義:表明的是0到9數字,兩個的數字包括在內。
例如:匹配規則爲「[0-9]」,那麼須要匹配的是一個數字。
10>.字符類"[a-zA-Z_0-9]"
含義:表明的字母或者數字或者下劃線(即單詞字符)。
例如:匹配規則爲"[a-zA-Z_0-9]",那麼須要匹配的是一個字母或者是一個數字或者一個下劃線。
11>.預約義字符類「.」
含義:表明的是任何字符。
例如:匹配規則爲「.」,那麼須要匹配的是一個任意字符。若是就想使用「.」的話,使用匹配規則"\\."來實現。
12>.預約義字符類「\d」
含義:表明的是的是0到9數字,兩頭的數字包括在內,至關於[0-9]。
例如:匹配規則爲「\d」,那麼須要匹配的是一個數字。
13>.預約義字符類「\w」
含義:表明的字母或者數字或者下劃線(即單詞字符),至關於[a-zA-Z_0-9]。
例如:匹配規則爲「\w」,那麼須要匹配的是一個字母或者是一個數字或者一個下滑線。
14>.邊界匹配器「^」
含義:表明的是行的開頭。
例如:匹配規則爲「^[abc][0-9]$」,那麼須要匹配的內容從[abc]這個位置開始,至關於左雙引號。
15>.邊界匹配器"$"
含義:表明的是行的結尾。
例如:匹配規則爲「\b[abc]\b」,那麼表明的是字母a或b或c的左右兩邊須要的是非單詞字符([a-zA-z_0-9])。
16>.數量詞"x?"
含義:表明的是x出現一次或一次的也沒有。
例如:匹配規則爲「a?」,那麼須要匹配的內容是多個字符‘a’,或者一個'a'都沒有。
17>.數量詞「x*」
含義:表明的是x出現零次或屢次。
例如:匹配規則爲「a*」,那麼須要匹配的內容是多個字符'a',或者一個'a'。
18>.數量詞「x+」
含義:表明的是x出現一次或屢次
例如:匹配規則爲「a+」,那麼須要匹配的內容是多個字符'a',或者一個‘a’。
19>.數量詞「X{n}」
含義:表明的是x出現剛好n次。
例如:匹配規則爲「a{5}」,那麼須要匹配的內容是5個字符‘a’。
20>.數量詞「X{n,}」
含義:表明的是X出現至少n次。
例如:匹配規則爲「a{5,8}」,那麼須要匹配的內容是有5個字符‘a’到8個字符‘a’之間。
1 構造 匹配 2 3 字符 4 x 字符 x 5 \\ 反斜線字符 6 \0n 帶有八進制值 0 的字符 n (0 <= n <= 7) 7 \0nn 帶有八進制值 0 的字符 nn (0 <= n <= 7) 8 \0mnn 帶有八進制值 0 的字符 mnn(0 <= m <= 三、0 <= n <= 7) 9 \xhh 帶有十六進制值 0x 的字符 hh 10 \uhhhh 帶有十六進制值 0x 的字符 hhhh 11 \t 製表符 ('\u0009') 12 \n 新行(換行)符 ('\u000A') 13 \r 回車符 ('\u000D') 14 \f 換頁符 ('\u000C') 15 \a 報警 (bell) 符 ('\u0007') 16 \e 轉義符 ('\u001B') 17 \cx 對應於 x 的控制符 18 19 字符類 20 [abc] a、b 或 c(簡單類) 21 [^abc] 任何字符,除了 a、b 或 c(否認) 22 [a-zA-Z] a 到 z 或 A 到 Z,兩頭的字母包括在內(範圍) 23 [a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](並集) 24 [a-z&&[def]] d、e 或 f(交集) 25 [a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](減去) 26 [a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](減去) 27 28 預約義字符類 29 . 任何字符(與行結束符可能匹配也可能不匹配) 30 \d 數字:[0-9] 31 \D 非數字: [^0-9] 32 \s 空白字符:[ \t\n\x0B\f\r] 33 \S 非空白字符:[^\s] 34 \w 單詞字符:[a-zA-Z_0-9] 35 \W 非單詞字符:[^\w] 36 37 POSIX 字符類(僅 US-ASCII) 38 \p{Lower} 小寫字母字符:[a-z] 39 \p{Upper} 大寫字母字符:[A-Z] 40 \p{ASCII} 全部 ASCII:[\x00-\x7F] 41 \p{Alpha} 字母字符:[\p{Lower}\p{Upper}] 42 \p{Digit} 十進制數字:[0-9] 43 \p{Alnum} 字母數字字符:[\p{Alpha}\p{Digit}] 44 \p{Punct} 標點符號:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ 45 \p{Graph} 可見字符:[\p{Alnum}\p{Punct}] 46 \p{Print} 可打印字符:[\p{Graph}\x20] 47 \p{Blank} 空格或製表符:[ \t] 48 \p{Cntrl} 控制字符:[\x00-\x1F\x7F] 49 \p{XDigit} 十六進制數字:[0-9a-fA-F] 50 \p{Space} 空白字符:[ \t\n\x0B\f\r] 51 52 java.lang.Character 類(簡單的 java 字符類型) 53 \p{javaLowerCase} 等效於 java.lang.Character.isLowerCase() 54 \p{javaUpperCase} 等效於 java.lang.Character.isUpperCase() 55 \p{javaWhitespace} 等效於 java.lang.Character.isWhitespace() 56 \p{javaMirrored} 等效於 java.lang.Character.isMirrored() 57 58 Unicode 塊和類別的類 59 \p{InGreek} Greek 塊(簡單塊)中的字符 60 \p{Lu} 大寫字母(簡單類別) 61 \p{Sc} 貨幣符號 62 \P{InGreek} 全部字符,Greek 塊中的除外(否認) 63 [\p{L}&&[^\p{Lu}]] 全部字母,大寫字母除外(減去) 64 65 邊界匹配器 66 ^ 行的開頭 67 $ 行的結尾 68 \b 單詞邊界 69 \B 非單詞邊界 70 \A 輸入的開頭 71 \G 上一個匹配的結尾 72 \Z 輸入的結尾,僅用於最後的結束符(若是有的話) 73 \z 輸入的結尾 74 75 Greedy 數量詞 76 X? X,一次或一次也沒有 77 X* X,零次或屢次 78 X+ X,一次或屢次 79 X{n} X,剛好 n 次 80 X{n,} X,至少 n 次 81 X{n,m} X,至少 n 次,可是不超過 m 次 82 83 Reluctant 數量詞 84 X?? X,一次或一次也沒有 85 X*? X,零次或屢次 86 X+? X,一次或屢次 87 X{n}? X,剛好 n 次 88 X{n,}? X,至少 n 次 89 X{n,m}? X,至少 n 次,可是不超過 m 次 90 91 Possessive 數量詞 92 X?+ X,一次或一次也沒有 93 X*+ X,零次或屢次 94 X++ X,一次或屢次 95 X{n}+ X,剛好 n 次 96 X{n,}+ X,至少 n 次 97 X{n,m}+ X,至少 n 次,可是不超過 m 次 98 99 Logical 運算符 100 XY X 後跟 Y 101 X|Y X 或 Y 102 (X) X,做爲捕獲組 103 104 Back 引用 105 \n 任何匹配的 nth 捕獲組 106 107 引用 108 \ Nothing,可是引用如下字符 109 \Q Nothing,可是引用全部字符,直到 \E 110 \E Nothing,可是結束從 \Q 開始的引用 111 112 特殊構造(非捕獲) 113 (?:X) X,做爲非捕獲組 114 (?idmsux-idmsux) Nothing,可是將匹配標誌i d m s u x on - off 115 (?idmsux-idmsux:X) X,做爲帶有給定標誌 i d m s u x on - off 116 的非捕獲組 (?=X) X,經過零寬度的正 lookahead 117 (?!X) X,經過零寬度的負 lookahead 118 (?<=X) X,經過零寬度的正 lookbehind 119 (?<!X) X,經過零寬度的負 lookbehind 120 (?>X) X,做爲獨立的非捕獲組
三.字符串類中設計正則表達式的經常使用方法
1>.matches(String regex)方法
做用:告知此字符串是否匹配給定的正則表達式。
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.Demo; 8 9 public class RegexDemo { 10 11 public static void main(String[] args) { 12 String QQ = "1053419035"; 13 String phone = "13021055038"; 14 System.out.println(checkQQ(QQ)); 15 System.out.println(checkTellphone(phone)); 16 17 } 18 19 //定義檢測QQ的方法。 20 public static boolean checkQQ(String QQ) { 21 String pattern = "[1-9][\\d]{4,9}"; 22 boolean res = QQ.matches(pattern); 23 return res; 24 } 25 26 // 27 public static boolean checkTellphone(String phone) { 28 String pattern = "1[34857][\\d]{9}"; 29 boolean res = phone.matches(pattern); 30 return res; 31 } 32 } 33 34 35 /* 36 以上代碼執行結果以下: 37 true 38 true 39 */
2>.split(String regex)方法
做用:根據給定正則表達式的匹配拆分此字符串。
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.Demo; 8 9 public class RegexDemo { 10 11 public static void main(String[] args) { 12 String src = "2018-04-17"; 13 String pattern = "-"; 14 System.out.println(getSplit(src,pattern)); 15 16 } 17 18 public static StringBuffer getSplit(String src,String pattern) { 19 String[] arr = src.split(pattern); 20 StringBuffer buffer = new StringBuffer(); 21 buffer.append("["); 22 for (int i = 0; i < arr.length; i++) { 23 if(i==arr.length-1) { 24 buffer.append(arr[i]+"]"); 25 }else { 26 buffer.append(arr[i]+","); 27 } 28 } 29 return buffer; 30 } 31 } 32 33 34 /* 35 以上代碼執行結果以下: 36 [2018,04,17] 37 */
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.Demo; 8 9 public class RegexDemo { 10 11 public static void main(String[] args) { 12 String src = "10 20 30 40 50 60 70"; 13 String pattern = " +"; //匹配多個空格。 14 System.out.println(getSplit(src,pattern)); 15 16 } 17 18 public static StringBuffer getSplit(String src,String pattern) { 19 String[] arr = src.split(pattern); 20 StringBuffer buffer = new StringBuffer(); 21 buffer.append("["); 22 for (int i = 0; i < arr.length; i++) { 23 if(i==arr.length-1) { 24 buffer.append(arr[i]+"]"); 25 }else { 26 buffer.append(arr[i]+","); 27 } 28 } 29 return buffer; 30 } 31 } 32 33 34 /* 35 以上代碼執行結果以下: 36 [10,20,30,40,50,60,70] 37 */
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.Demo; 8 9 public class RegexDemo { 10 11 public static void main(String[] args) { 12 String ipconfig = "192.168.0.254"; 13 String pattern = "\\."; //咱們須要對"."進行轉義。 14 System.out.println(getSplit(ipconfig,pattern)); 15 16 } 17 18 public static StringBuffer getSplit(String src,String pattern) { 19 String[] arr = src.split(pattern); 20 StringBuffer buffer = new StringBuffer(); 21 buffer.append("["); 22 for (int i = 0; i < arr.length; i++) { 23 if(i==arr.length-1) { 24 buffer.append(arr[i]+"]"); 25 }else { 26 buffer.append(arr[i]+","); 27 } 28 } 29 return buffer; 30 } 31 } 32 33 34 /* 35 以上代碼執行結果以下: 36 [10,20,30,40,50,60,70] 37 */
3>.replaceAll(String regex,String replacenent)方法
做用:使用給定的replacement替換此字符串全部匹配給定的正則表達式的子字符串。
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.Demo; 8 9 public class RegexDemo { 10 11 public static void main(String[] args) { 12 String src = "2018yinzhengjie@0417"; 13 System.out.println("切割以前:>>>"+src); 14 String re = "$"; 15 re = java.util.regex.Matcher.quoteReplacement(re); //一個是JDK提供的方法,對特殊字符進行處理. 16 src = src.replaceAll("[\\d]+", re); 17 System.out.println("切割以後:>>>"+src); 18 } 19 } 20 21 22 /* 23 以上代碼執行結果以下: 24 切割以前:>>>2018yinzhengjie@0417 25 切割以後:>>>$yinzhengjie@$ 26 */
4>.匹配正確的數字
1 匹配規則: 2 1>.匹配正整數:"\\d+"; 3 2>.匹配正小數:"\\d+\\.\\d+" ; 4 3>.匹配負整數:"-\\d+"; 5 4>.匹配負小數:"-\\d+.\\d+"
6 5>.匹配保留兩位小數的整數:"\\d+\\.\\d{2}"
7 6>.匹配保留1-3位小數的整數:「\\d+\\.\\d{1,3}」
四.小試牛刀
1>.郵箱地址匹配
下面的一個案例是對用戶輸入的郵箱進行合法性判斷,固然實際生產環境中比這個要複雜的多,咱們這裏只是判斷用戶輸入的郵箱地址是否合法。
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.Demo; 8 9 import java.util.Scanner; 10 11 public class RegexDemo { 12 13 public static void main(String[] args) { 14 Scanner s = new Scanner(System.in); 15 s.useDelimiter("\n"); 16 while(true) { 17 System.out.print("請輸入您想要註冊的郵箱(輸入'exit'退出程序):>>>"); 18 String Email = s.nextLine(); 19 if(Email.equals("exit")) { 20 System.exit(0); 21 } 22 if(checkMail(Email) == true) { 23 System.out.println("您輸入的郵箱格式正確!"); 24 }else { 25 System.out.println("您輸入的郵箱格式錯誤!"); 26 } 27 } 28 29 } 30 31 //定義郵箱的匹配規則 32 public static boolean checkMail(String Email) { 33 String pattern = "[a-zA-Z0-9_]+@[0-9a-z]+(\\.[a-z]+)+"; 34 boolean res = Email.matches(pattern); 35 return res; 36 } 37 }
下圖是我測試的結果:
2>.統計單詞出現的次數
咱們能夠手動輸入一些字符串,而後讓程序自動統計出來單詞出現的次數,實現代碼以下:
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.demo; 8 9 import java.util.HashMap; 10 import java.util.Scanner; 11 import java.util.Set; 12 import java.util.regex.Matcher; 13 import java.util.regex.Pattern; 14 15 16 public class WordCountDemo { 17 18 public static void main(String[] args) { 19 Scanner sc = new Scanner(System.in); 20 System.out.print("input a string:"); 21 String s = sc.nextLine(); 22 23 HashMap<String, Integer> hm = new HashMap<>(); 24 25 Pattern p = Pattern.compile("\\b\\w+\\b"); 26 Matcher m = p.matcher(s); 27 while(m.find()){ 28 String word = m.group(); 29 if(!hm.containsKey(word)){ 30 hm.put(word, 1); 31 }else{ 32 hm.put(word, hm.get(word) + 1); 33 } 34 } 35 36 Set<String> keys = hm.keySet(); 37 for (String word : keys) { 38 System.out.println("單詞是: " + word +"\t次數是: "+ hm.get(word)); 39 } 40 } 41 }
測試結果以下: