一文搞懂正則表達(dá)式基礎(chǔ)語(yǔ)法以及如何應(yīng)用
一、正則表達(dá)式
1、基本介紹
? 概述
- 一個(gè)正則表達(dá)式,就是用某種模式去匹配字符串的一個(gè)公式。很多人因?yàn)樗鼈兛瓷先ケ容^古怪而且復(fù)雜所以不敢去使用,不過(guò),經(jīng)過(guò)練習(xí)后就覺(jué)得這些復(fù)雜的表達(dá)式寫(xiě)起來(lái)還是相當(dāng)簡(jiǎn)單的, 而且, 一旦你弄懂它們,你就能把數(shù)小時(shí)辛苦而且易錯(cuò)的文本處理工作縮短在幾分鐘(甚至幾秒鐘)內(nèi)完成。
- 正則表達(dá)式不是只有java才有,實(shí)際上很多編程語(yǔ)言都支持正則表達(dá)式進(jìn)行字符串操作!
? 快速入門(mén)
public class RegTheory {
public static void main(String[] args) {
//目標(biāo):匹配所有四個(gè)數(shù)字
String content = "2002fsd ke ire i2222 ";
//1. \\d 表示一個(gè)任意的數(shù)字
String regStr = "(\\d\\d)(\\d\\d)";
//2. 創(chuàng)建模式對(duì)象[即正則表達(dá)式對(duì)象]
Pattern pattern = Pattern.compile(regStr);
//3. 創(chuàng)建匹配器
//說(shuō)明:創(chuàng)建匹配器 matcher, 按照 正則表達(dá)式的規(guī)則 去匹配 content 字符串
Matcher matcher = pattern.matcher(content);
//4. 開(kāi)始匹配
while (matcher.find()) {
System.out.println("找到: " + matcher.group(0));
System.out.println("第 1 組()匹配到的值=" + matcher.group(1));
System.out.println("第 2 組()匹配到的值=" + matcher.group(2));
}
}
}? 底層源碼
matcher.find() 完成的任務(wù) (考慮分組),{什么是分組,比如 (\d\d)(\d\d) ,正則表達(dá)式中有() 表示分組,第 1 個(gè)()表示第 1 組,第 2 個(gè)()表示第 2 組...}
1. 根據(jù)指定的規(guī)則 , 定位滿足規(guī)則的子字符串 ( 比如 (20)(02))
2. 找到后,將 子字符串的開(kāi)始的索引記錄到 matcher 對(duì)象的屬性 int[ ] groups;
? groups[0] = 0 , 把該子字符串的結(jié)束的索引+1 的值記錄到 groups[1] = 4
? 記錄 1 組 () 匹配到的字符串 groups[2] = 0 groups[3] = 2
? 記錄 2 組 () 匹配到的字符串 groups[4] = 2 groups[5] = 4
? 如果有更多的分組.....
3. 同時(shí)記錄 oldLast 的值為 子字符串的結(jié)束的 索引 +1 的值即 16, 即下次執(zhí)行 find 時(shí),就從 16 開(kāi)始匹配。
? matcher.group(0) 分析
public String group(int group) {
if (first < 0){
throw new IllegalStateException("No match found");
}
if (group < 0 || group > groupCount()){
throw new IndexOutOfBoundsException("No group " + group);
}
if ((groups[group*2] == -1) || (groups[group*2+1] == -1)){
return null;
}
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}根據(jù) groups[0]=16 和 groups[1]=20 的記錄的位置,從 content 開(kāi)始截取子字符串返回
就是 [16,20) 包含 16 但是不包含索引為 20 的位置 如果再次指向 find 方法 . 仍然安上面分析來(lái)執(zhí)行。
? 小結(jié)
1. 如果正則表達(dá)式有() 即分組
2. 取出匹配的字符串規(guī)則如下
3. group(0) 表示匹配到的子字符串
4. group(1) 表示匹配到的子字符串的第一組字串
5. group(2) 表示匹配到的子字符串的第 2 組字串
6. ... 但是分組的數(shù)不能越界.

2、正則表達(dá)式語(yǔ)法
? 基本介紹
如果要想靈活的運(yùn)用正則表達(dá)式,必須了解其中各種元字符的功能,元字符從功能上大致分為:
①限定符,②選擇匹配符,③分組組合和反向引用符,④特殊字符,⑤字符匹配符,⑥定位符
? 元字符(Metacharacter)-轉(zhuǎn)義號(hào)
符號(hào)說(shuō)明: 在我們使用正則表達(dá)式去檢索某些特殊字符的時(shí)候,需要用到轉(zhuǎn)義符號(hào)。則檢索不到結(jié)果,甚至?xí)?bào)錯(cuò)的。 案例:用$ 去匹配 “abc$(" 會(huì)怎樣?
在Java的正則表達(dá)式中,兩個(gè)\\ 代表其他語(yǔ)言中的一個(gè)\
需要用到轉(zhuǎn)義符號(hào)的字符有以下 : " . * + () $ / \ ? [ ] ^ { } "
二、正則語(yǔ)法
1、字符匹配符、選擇匹配符
? 基本介紹


? 代碼實(shí)現(xiàn)
String content = "a11c8abc _ABCy @"; String regStr = "[a-z]"; //匹配 a-z 之間任意一個(gè)字符 String regStr = "[A-Z]"; //匹配 A-Z 之間任意一個(gè)字符 String regStr = "abc"; //匹配 abc 字符串[默認(rèn)區(qū)分大小寫(xiě)] String regStr = "(?i)abc"; //匹配 abc 字符串[不區(qū)分大小寫(xiě)] String regStr = "[0-9]"; //匹配 0-9 之間任意一個(gè)字符 String regStr = "[^a-z]"; //匹配 不在 a-z 之間任意一個(gè)字符 String regStr = "[^0-9]"; //匹配 不在 0-9 之間任意一個(gè)字符 String regStr = "[abcd]"; //匹配 在 abcd 中任意一個(gè)字符 String regStr = "\\D"; //匹配 不在 0-9 的任意一個(gè)字符 String regStr = "\\w"; //匹配 大小寫(xiě)英文字母, 數(shù)字,下劃線 String regStr = "\\W"; //匹配 等價(jià)于 [^a-zA-Z0-9_] // \\s 匹配任何空白字符(空格,制表符等) String regStr = "\\s"; // \\S 匹配任何非空白字符 ,和\\s 剛好相反 String regStr = "\\S"; //. 匹配出 \n 之外的所有字符,如果要匹配.本身則需要使用 \\. String regStr = ".";
//當(dāng)創(chuàng)建 Pattern 對(duì)象時(shí),指定 Pattern.CASE_INSENSITIVE, 表示匹配是不區(qū)分字母大小寫(xiě). Pattern pattern = Pattern.compile(regStr, Pattern.CASE_INSENSITIVE);
? 選擇匹配符

String content = "study hard"; String regStr = "t|a|r";
2、限定符
? 基本介紹


? 代碼實(shí)現(xiàn)
String content = "a211111aaaaaahello";
String regStr = "a{3}"; // 表示匹配 aaa
String regStr = "1{4}"; // 表示匹配 1111
String regStr = "\\d{2}"; // 表示匹配 兩位的任意數(shù)字字符
//細(xì)節(jié):java 匹配默認(rèn)貪婪匹配,即盡可能匹配多的
String regStr = "a{3,4}"; //表示匹配 aaa 或者 aaaa
String regStr = "1{4,5}"; //表示匹配 1111 或者 11111
String regStr = "\\d{2,5}"; //匹配 2 位數(shù)或者 3,4,5
//1+
String regStr = "1+"; //匹配一個(gè) 1 或者多個(gè) 1
String regStr = "\\d+"; //匹配一個(gè)數(shù)字或者多個(gè)數(shù)字
//1*
String regStr = "1*"; //匹配 0 個(gè) 1 或者多個(gè) 1
//遵守貪婪匹配
String regStr = "a1?"; //匹配 a 或者 a13、定位符
? 基本介紹

? 代碼實(shí)現(xiàn)
String content = "123-abc sldkjfs s dfsjf"; String content = "123-abc"; //以至少 1 個(gè)數(shù)字開(kāi)頭,后接任意個(gè)小寫(xiě)字母的字符串 String regStr = "^[0-9]+[a-z]*"; //以至少 1 個(gè)數(shù)字開(kāi)頭, 必須以至少一個(gè)小寫(xiě)字母結(jié)束 String regStr = "^[0-9]+\\-[a-z]+$"; //表示匹配邊界的 han[這里的邊界是指:被匹配的字符串最后,也可以是空格的子字符串的后面] String regStr = "han\\b"; //和\\b 的含義剛剛相反 String regStr = "han\\B";
4、分組
? 基本介紹


? 代碼實(shí)現(xiàn)
String content = "hello world s7789 nn1189han";
//命名分組: 即可以給分組取名
String regStr = "(?<g1>\\d\\d)(?<g2>\\d\\d)";//匹配 4 個(gè)數(shù)字的字符串
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("找到=" + matcher.group(0));
System.out.println("第 1 個(gè)分組內(nèi)容=" + matcher.group(1));
System.out.println("第 1 個(gè)分組內(nèi)容[通過(guò)組名]=" + matcher.group("g1"));
System.out.println("第 2 個(gè)分組內(nèi)容=" + matcher.group(2));
System.out.println("第 2 個(gè)分組內(nèi)容[通過(guò)組名]=" + matcher.group("g2"));
}三、常用類(lèi)
1、基本介紹
? 概述
? java.util.regex 包主要包括以下三個(gè)類(lèi)Pattern 類(lèi)、Matcher 類(lèi)和 PatternSyntaxException ? Pattern 類(lèi)
pattern 對(duì)象是一個(gè)正則表達(dá)式對(duì)象。Pattern 類(lèi)沒(méi)有公共構(gòu)造方法。要?jiǎng)?chuàng)建一個(gè)Pattern 對(duì)象 調(diào)用其公共靜態(tài)方法,它返回一個(gè)Pattern 對(duì)象。該方法接受一個(gè)正則表達(dá)式作為它的第一個(gè)參數(shù),比如: Pattern r=Pattern.compile(pattern);
? Matcher類(lèi)
Matcher對(duì)象是對(duì)輸入字符串進(jìn)行解釋和匹配的引擎。 與Pattern 類(lèi)一樣, Matcher 也沒(méi)有公共構(gòu)造方法。 你需要調(diào)用 Pattern 對(duì)象的 matcher方法來(lái)獲得一個(gè) Matcher對(duì)象
? PatternSyntaxException
PatternSyntaxException 是一個(gè)非強(qiáng)制異常類(lèi), 它表示一個(gè)正則表達(dá)式模式中的語(yǔ)法錯(cuò)誤。
? 代碼實(shí)例
public class PatternMethod {
public static void main(String[] args) {
String content = "hello abc hello, 努力學(xué)習(xí)";
//String regStr = "hello";
String regStr = "hello.*";
boolean matches = Pattern.matches(regStr, content);
System.out.println("整體匹配= " + matches);
}
}? Matcher 常用類(lèi)
public class MatcherMethod {
public static void main(String[] args) {
String content = "hello edu jack edutom hello smith hello edu edu";
String regStr = "hello";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println(matcher.start());
System.out.println(matcher.end());
System.out.println("找到: " + content.substring(matcher.start(), matcher.end()));
}
//整體匹配方法,常用于,去校驗(yàn)?zāi)硞€(gè)字符串是否滿足某個(gè)規(guī)則
System.out.println("整體匹配=" + matcher.matches());
//完成如果 content 有 edu 替換成 努力學(xué)習(xí)
regStr = "edu";
pattern = Pattern.compile(regStr);
matcher = pattern.matcher(content);
//注意:返回的字符串才是替換后的字符串 原來(lái)的 content 不變化
String newContent = matcher.replaceAll("努力學(xué)習(xí)");
System.out.println("newContent=" + newContent);
System.out.println("content=" + content);
}
}2、分組、捕獲、反向引用
? 基本介紹
1、分組
我們可以用圓括號(hào)組成一個(gè)比較復(fù)雜的匹配模式,那么一個(gè)圓括號(hào)的部分我們可以看作是一個(gè)子表達(dá)式(一個(gè)分組)。
2、捕獲
把正則表達(dá)式中子表達(dá)式(分組匹配)的內(nèi)容,保存到內(nèi)存中以數(shù)字編號(hào)或顯式命名的組里, 方便后面引用, 從左向右,以分組的左括號(hào)為標(biāo)志,第一個(gè)出現(xiàn)的分組的組號(hào)為1,第二個(gè)為2,以以此類(lèi)推,組0代表的是整個(gè)正則式。
3、反向引用
圓括號(hào)的內(nèi)容被捕獲后,可以在這個(gè)括號(hào)后被使用, 從而寫(xiě)出一個(gè)比較實(shí)用的匹配式,這個(gè)我們稱為反向引用,這種引用既可以是在正則表達(dá)式內(nèi)部,也可以是在正則表達(dá)式外部,內(nèi)部反向引用\\分組號(hào),外部反向引用$分組號(hào)。
? 經(jīng)典案例
public class RegExp13 {
public static void main(String[] args) {
String content = "我....我要....學(xué)學(xué)學(xué)學(xué)....編程 java!";
//1. 去掉所有的.
Pattern pattern = Pattern.compile("\\.");
Matcher matcher = pattern.matcher(content);
content = matcher.replaceAll("");
//2. 去掉重復(fù)的字 我我要學(xué)學(xué)學(xué)學(xué)編程 java!
//(1) 使用 (.)\\1+
//(2) 使用 反向引用$1 來(lái)替換匹配到的內(nèi)容
// 注意:因?yàn)檎齽t表達(dá)式變化,所以需要重置 matcher
pattern = Pattern.compile("(.)\\1+");//分組的捕獲內(nèi)容記錄到$1
matcher = pattern.matcher(content);
//使用 反向引用$1 來(lái)替換匹配到的內(nèi)容
content = matcher.replaceAll("$1");
System.out.println("content=" + content);
}
}3、String 類(lèi)中使用正則表達(dá)式
? 替換功能
String 類(lèi): public String replaceAll(String regex,String replacement)
? 判斷功能
String 類(lèi): public boolean matches(String regex){} // 使用 Pattern 和 Matcher 類(lèi)
? 分割功能
String 類(lèi): public String[] split(String regex)
? 代碼實(shí)例
String content = "2000 年 5 月,JDK1.3、JDK1.4 和 J2SE1.3 相繼發(fā)布。";
//使用正則表達(dá)式方式,將 JDK1.3 和 JDK1.4 替換成 JDK
content = content.replaceAll("JDK1\\.3|JDK1\\.4", "JDK");
System.out.println(content);//要求 驗(yàn)證一個(gè) 手機(jī)號(hào), 要求必須是以 138 139 開(kāi)頭的
content = "13888889999";
if (content.matches("1(38|39)\\d{8}")) {
System.out.println("驗(yàn)證成功");
} else {
System.out.println("驗(yàn)證失敗");
}//要求按照 # 或者 - 或者 ~ 或者 數(shù)字 來(lái)分割
content = "hello#abc-jack12smith~北京";
String[] split = content.split("#|-|~|\\d+");
for (String s : split) {
System.out.println(s);
}總結(jié)
到此這篇關(guān)于正則表達(dá)式基礎(chǔ)語(yǔ)法以及如何應(yīng)用的文章就介紹到這了,更多相關(guān)正則表達(dá)式基礎(chǔ)語(yǔ)法及應(yīng)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PHP preg_replace() 正則替換所有符合條件的字符串
PHP preg_replace() 正則替換,與Javascript 正則替換不同,PHP preg_replace() 默認(rèn)就是替換所有符號(hào)匹配條件的元素2014-02-02
關(guān)于正則表達(dá)式基本語(yǔ)法的應(yīng)用詳解(必看篇)
下面小編就為大家?guī)?lái)一篇關(guān)于正則表達(dá)式基本語(yǔ)法的應(yīng)用詳解(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
8個(gè)你應(yīng)該了解的正則表達(dá)式提高你的工作效率
正則表達(dá)式也可以被當(dāng)作是一門(mén)語(yǔ)言,入門(mén)時(shí)可能很吃力,不過(guò)一旦學(xué)會(huì)了就方便很多,在處理一些比較復(fù)雜的替換時(shí),正則表達(dá)式就會(huì)發(fā)揮它的真正作用,本文整理了一些常用的正則,感興趣的朋友可以了解下,或許對(duì)你有所幫助2013-01-01
最新最全的手機(jī)號(hào)驗(yàn)證正則表達(dá)式
我們?cè)匍_(kāi)發(fā)項(xiàng)目時(shí),總是要用到一些正則驗(yàn)證,就數(shù)手機(jī)號(hào)碼規(guī)則比較難收集,這篇文章主要給大家介紹了關(guān)于最新最全的手機(jī)號(hào)驗(yàn)證正則表達(dá)式,需要的朋友可以參考下2022-02-02
淺談?wù)齽t表達(dá)式(Regular Expression)
本文介紹了正則表達(dá)式的一些學(xué)習(xí)內(nèi)容,以及在Javascript、PHP下如何使用正則表達(dá)式2014-08-08
用正則取出html頁(yè)面中script段落里的內(nèi)容
用正則取出html頁(yè)面中script段落里的內(nèi)容...2007-03-03
自動(dòng)識(shí)別HTML的標(biāo)記 替換連接
自動(dòng)識(shí)別HTML的標(biāo)記 替換連接...2006-07-07

