------ Java教育訓練、Android教育訓練、java學習型部落格、期待與您交流! ------- 一、正規表達式概述。 正規表達式:符合一定規則的表達式。 作用:專門作用于字元串,對字元串進行一些特殊的操作。 意義:操縱字元串的時候可以使用String類中的方法進行組合來操作,但是這樣的話代碼顯得過于複雜,邏輯思路也不太清晰,使用起來非常不友善。如果使用正規表達式來操作的話就顯得簡單明了了。 好處:可以簡化對字元串的複雜操作。 弊端:符号定義越多,正則越長,閱讀性越差。 二、正規表達式執行個體。 功能需求:對手機号碼進行檢驗:位數隻能是11位,不能以0開頭,隻能是數字,不能包含特殊字元。 方法一:使用String類中的方法組合來完成。 代碼:
package it.heima;
public class RegexDemo {
public static void main(String[] args) {
checkPhone();
}
public static void checkPhone(){
//定義一個需要檢驗的電話号碼
String phone = "119p1111111";
//取得電話号碼的長度
int length = phone.length();
//如果是以0開頭則提示錯誤,否則進入判斷。
if(!(phone.startsWith("0"))) {
//如果長度不等于11,則提示錯誤,否則進入判斷。
if(length == 11) {
//取得電話字元串的字元數組
char[] phoneChar = phone.toCharArray();
//定義标志,用于标記目前字元是否為0-9
boolean flag = false;
//取得目前的字元,如果在0-9之間則把标志設定為true,否則設定為false.
for (int i = 0; i < phoneChar.length; i++) {
if(phoneChar[i] >= '0' && phoneChar[i] <= '9') {
flag = true;
} else {
flag = false;
break;
}
}
if(flag) {
System.out.println("電話号碼正常");
} else{
System.out.println("電話号碼隻能為數字");
}
} else{
System.out.println("電話号碼長度隻能為11位");
}
} else {
System.out.println("電話号碼不能以0開頭");
}
}
}
運作結果:
方法二:使用正規表達式。 代碼:
package it.heima;
public class RegexDemo {
public static void main(String[] args) {
checkPhone();
}
public static void checkPhone(){
//定義電話字元串
String phone = "2w111111234";
//定義一個正規表達式規則,第一個字元隻能是1-9之間,從第二為字元開始隻能是在0-9之間,并且隻能是10位。
String regex = "[1-9][0-9]{10}";
//判斷電話字元串是否比對正規表達式
boolean flag = phone.matches(regex);
if(flag) {
System.out.println("phone is ok");
}else{
System.out.println("phone is not ok");
}
}
}
運作結果:
由上面這個列子可以看出正規表達式對檢驗字元串是很友善的。那麼正規表達式的具體功能有些上面呢? 三、正規表達式的操作功能: (1)比對:String matches方法。用規則比對整個字元串,隻要有一處不符合規則,就比對結束,傳回false。上面講的對電話号碼的檢驗就是一個比對的列子。 (2)切割:String split方法。用規則切割整個字元換。 需求:把字元串按重疊字元進行切割,比如字元串“wangaajiebblovettheima”按重疊字元切割後結果是wang jie love heima
代碼:
package it.heima;
public class RegtexQG {
public static void main(String[] args) {
//定義被切割的字元串
String str = "wangaajiebblovettheima";
//定義切割規則
String regex = "(.)\\1";
regex_mth1(str, regex);
}
/**
* 字元串切割功能
* @param str 被切割的字元串
* @param regex 切割的規則
*/
public static void regex_mth1(String str,String regex) {
String[] strResult = str.split(regex);
for(String str1 : strResult) {
System.out.println(str1);
}
}
}
運作結果:
(3)替換:String replaceAll方法。
需求:把一個字元串中連續超過5個的數字替換為#,例如dhfkj546567dhj12fkdhk33431234eur替換後的結果為:dhfkj#dhj12fkdhk#eur
代碼:
package it.heima;
public class RegexTh {
public static void main(String[] args) {
String str = "dhfkj546567dhj12fkdhk33431234eur";
String regex = "\\d{5,}";
String newStr = "#";
regex_mth(str, regex, newStr);
}
/**
* 把字元串中滿足一定規則的子字元串替換為新的字元串
* @param str 原字元串
* @param regex 規則
* @param newStr 替換成的字元串
*/
public static void regex_mth(String str, String regex,String newStr) {
str = str.replaceAll(regex, newStr);
System.out.println(str);
}
}
運作結果:
(4)擷取:将字元串中符合規則的子串取出。
需求:把一句英文中字母數為三個的英文單詞擷取出來。例如,“ni hao ma hei ma wo lai le”,擷取後結果為:“hao hei lai”
代碼:
package it.heima;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexHQ {
public static void main(String[] args) {
regex_meth();
}
public static void regex_meth() {
//定義字元串
String str = "ni hao ma hei ma wo lai le";
//定義擷取規則
String regex = "\\b[a-z]{3}\\b";
//把規則封裝成對象
Pattern p = Pattern.compile(regex);
//讓正則對象和要作用的字元串相關聯,擷取比對器對象。
Matcher m = p.matcher(str);
while(m.find()) {
System.out.println(m.group());
}
}
}
運作結果:
可以看出正規表達式操作字元串還是很友善的。 另附正規表達式構造摘要。 正規表達式的構造摘要:
字元
x 字元 x
\\ 反斜線字元
\0n 帶有八進制值 0 的字元 n (0 <= n <= 7)
\0nn 帶有八進制值 0 的字元 nn (0 <= n <= 7)
\0mnn 帶有八進制值 0 的字元 mnn(0 <= m <= 3、0 <= n <= 7)
\xhh 帶有十六進制值 0x 的字元 hh
\uhhhh 帶有十六進制值 0x 的字元 hhhh
\t 制表符 ('\u0009')
\n 新行(換行)符 ('\u000A')
\r 回車符 ('\u000D')
\f 換頁符 ('\u000C')
\a 報警 (bell) 符 ('\u0007')
\e 轉義符 ('\u001B')
\cx 對應于 x 的控制符
字元類
[abc] a、b 或 c(簡單類)
[^abc] 任何字元,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,兩頭的字母包括在内(範圍)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](減去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](減去)
預定義字元類
. 任何字元(與行結束符可能比對也可能不比對)
\d 數字:[0-9]
\D 非數字: [^0-9]
\s 空白字元:[ \t\n\x0B\f\r]
\S 非空白字元:[^\s]
\w 單詞字元:[a-zA-Z_0-9]
\W 非單詞字元:[^\w]
POSIX 字元類(僅 US-ASCII)
\p{Lower} 小寫字母字元:[a-z]
\p{Upper} 大寫字母字元:[A-Z]
\p{ASCII} 所有 ASCII:[\x00-\x7F]
\p{Alpha} 字母字元:[\p{Lower}\p{Upper}]
\p{Digit} 十進制數字:[0-9]
\p{Alnum} 字母數字字元:[\p{Alpha}\p{Digit}]
\p{Punct} 标點符号:!"#$%&'()*+,-./:;<=>[email protected][\]^_`{|}~
\p{Graph} 可見字元:[\p{Alnum}\p{Punct}]
\p{Print} 可列印字元:[\p{Graph}\x20]
\p{Blank} 空格或制表符:[ \t]
\p{Cntrl} 控制字元:[\x00-\x1F\x7F]
\p{XDigit} 十六進制數字:[0-9a-fA-F]
\p{Space} 空白字元:[ \t\n\x0B\f\r]
java.lang.Character 類(簡單的 java 字元類型)
\p{javaLowerCase} 等效于 java.lang.Character.isLowerCase()
\p{javaUpperCase} 等效于 java.lang.Character.isUpperCase()
\p{javaWhitespace} 等效于 java.lang.Character.isWhitespace()
\p{javaMirrored} 等效于 java.lang.Character.isMirrored()
Unicode 塊和類别的類
\p{InGreek} Greek 塊(簡單塊)中的字元
\p{Lu} 大寫字母(簡單類别)
\p{Sc} 貨币符号
\P{InGreek} 所有字元,Greek 塊中的除外(否定)
[\p{L}&&[^\p{Lu}]] 所有字母,大寫字母除外(減去)
邊界比對器
^ 行的開頭
$ 行的結尾
\b 單詞邊界
\B 非單詞邊界
\A 輸入的開頭
\G 上一個比對的結尾
\Z 輸入的結尾,僅用于最後的結束符(如果有的話)
\z 輸入的結尾
Greedy 數量詞
X? X,一次或一次也沒有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超過 m 次
Reluctant 數量詞
X?? X,一次或一次也沒有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰好 n 次
X{n,}? X,至少 n 次
X{n,m}? X,至少 n 次,但是不超過 m 次
Possessive 數量詞
X?+ X,一次或一次也沒有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰好 n 次
X{n,}+ X,至少 n 次
X{n,m}+ X,至少 n 次,但是不超過 m 次
Logical 運算符
XY X 後跟 Y
X|Y X 或 Y
(X) X,作為捕獲組
Back 引用
\n 任何比對的 nth 捕獲組
引用
\ Nothing,但是引用以下字元
\Q Nothing,但是引用所有字元,直到 \E
\E Nothing,但是結束從 \Q 開始的引用
特殊構造(非捕獲)
(?:X) X,作為非捕獲組
(?idmsux-idmsux) Nothing,但是将比對标志i d m s u x on - off
(?idmsux-idmsux:X) X,作為帶有給定标志 i d m s u x on - off
的非捕獲組 (?=X) X,通過零寬度的正 lookahead
(?!X) X,通過零寬度的負 lookahead
(?<=X) X,通過零寬度的正 lookbehind
(?<!X) X,通過零寬度的負 lookbehind
(?>X) X,作為獨立的非捕獲組