正則表達式高級用法之分組的使用教程
分組的使用場景
在書寫正則表達式時,通常情況下,我們有兩種場景會使用到分組。
一是:對一個子表達式進行重復(fù);二是:想要獲取到子表達式匹配到的內(nèi)容。
- 對子表達式進行重復(fù)
如果需要重復(fù)單個字符,直接在字符后面加上限定符即可,例如 a+
表示匹配1個或一個以上的a,a?
表示匹配0個或1個a。
但是我們?nèi)绻獙Χ鄠€字符進行重復(fù)的話,就需要用到 分組 。
比如:(ab){3}
表示 ab 字符重復(fù)3次
正則中常用的限定符如下:
表達式 | 說明 |
---|---|
X ? | X ,一次或一次也沒有 |
X * | X ,零次或多次 |
X + | X ,一次或多次 |
X { n } | X ,恰好 n 次 |
X { n ,} | X ,至少 n 次 |
X { n , m } | X ,至少 n 次,但是不超過 m 次 |
- 獲取到子表達式匹配到的內(nèi)容
比如表達式: [a-z]*\d*[a-z]*
,它表示a-z的字符重復(fù)0到多次,后面緊跟0到多個數(shù)字,后面再跟上多個a-z的字符。
顯然,字符串 abcd324232efg
是滿足匹配的串。那么,如果我們只想要獲取到匹配串中數(shù)字 324232
后面的串 efg
呢?
這時,就可以通過分組的方式來改寫正則表達式: [a-z]*\d*([a-z]*)
。這樣,我們就可以通過獲取第 1 個分組匹配到的內(nèi)容來達到目的。
分組的使用方法
正則中通過小括號“()”
來指定需要重復(fù)的子表達式,然后再加上限定符對這個子表達式進行重復(fù)。
例如:(abc)? 表示0個或1個abc 。
一組括號里面的表達式就表示一個分組 。
捕獲組
分組可以分為兩種形式,捕獲組和非捕獲組。
捕獲組和非捕獲組的區(qū)別就是:捕獲組表示的分組會捕獲文本(即:匹配字符),而非捕獲組表示的分組不會捕獲文本。
捕獲組可以通過從左到右計算其開括號來編號 。
例如,在表達式 (A)(B(C)) 中,存在四個這樣的組:
分組編號 | 分組編號對應(yīng)的子表達式 |
---|---|
0 | (A)(B(C)) |
1 | (A) |
2 | (B(C)) |
3 | (C) |
注意:第0個分組始終代表整個表達式
分組的序號可以通過 Back 引用(反向引用) 在表達式中使用,也可以在匹配操作完成后從匹配器檢索出分組匹配到的內(nèi)容。
反向引用的知識將會在后續(xù)的文章中進行分析。
分組的使用實例
在一個完整的正則中,如果我們只想獲取到某個子表達式匹配到的內(nèi)容,就可以通過分組來達到目的。
比如:
待匹配串:abcd324232efg
想要獲取到這個字符串中第二次連續(xù)出現(xiàn)的字母子串efg
我們可以通過分組的方式書寫正則: [a-z]*\d*([a-z]*)
。
可以看到,我們通過子表達式([a-z]*)
來匹配第二次連續(xù)出現(xiàn)之母的子串,并且通過()
添加了分組,這樣,我們就可以通過分組來獲取到相應(yīng)的匹配內(nèi)容了。
具體的獲取方法不同的語言的語法可能會有差異,但是原理是相通的。
下面就來看一下 javascript 和 java 中是如何進行處理的?
javascript 獲取分組內(nèi)容
var str = "abcd324232efg"; var reg = new RegExp("([a-z]*)(\\d*)([a-z]*)"); var arr = str.match(reg); // 顯示匹配到的分組內(nèi)容 alert(arr[0] + "===" + arr[1] + "===" + arr[2] + "===" + arr[3]); alert(RegExp.$1 + "-----" + RegExp.$2 + "----" + RegExp.$3);
上面的例子中,我添加了 3 個分組。
通過 arr[n]
和 RegExp.$n
的方式都能獲取到分組匹配內(nèi)容。
在 javascript 中
\d
需要進行轉(zhuǎn)義
java 獲取分組內(nèi)容
public static void main(String[] args) { String str = "abcd324232efg"; Pattern pattern = Pattern.compile("([a-z]*)(\\d*)([a-z]*)"); Matcher matcher = pattern.matcher(str); if (matcher.find()) { System.out.println(matcher.group()); System.out.println(matcher.group(0)); System.out.println(matcher.group(1)); System.out.println(matcher.group(2)); System.out.println(matcher.group(3)); } }
在 java 中,通過 Matcher.group(n)
的方式拿到分組匹配內(nèi)容。
在 javascript 中
\d
需要進行轉(zhuǎn)義
小結(jié)
分組通常有兩種使用場景:一是:對一個子表達式進行重復(fù);二是:想要獲取到子表達式匹配到的內(nèi)容。
分組是通過 ()
來表示的,它是通過從左到右計算其開括號來進行編號的。
補充:正則表達式分組及常見的方法
/* * 正則表達式分組功能: * 捕獲組可以通過從左到右計算其開括號來編號。例如,在表達式 ((A)(B(C))) 中,存在四個這樣的組: * split(regex) 參數(shù)是正則表達式 返回值是一個數(shù)組 * replaceAll(regex,replacement) 第一個參數(shù)是正則表達式, 第二個參數(shù)要替換成的字符串 */ import java.util.Arrays; public class RegexApply { public static void main(String[] args) { // TODO Auto-generated method stub // demo1(); // demo2(); // demo3(); // demo4(); // demo5(); // demo6(); } private static void demo6() { /* * \\. "" 將所有的. 替換為空字符串 * (.)\\1+ "$1" 將第一組出現(xiàn)的多次都替換 第一組出現(xiàn)的一次 $ 代表首字符 */ String s = "我..我我...我....愛..愛愛愛....愛愛..學.學學..學學學...學習習..習...習.習.習......習習習習"; String s2 = s.replaceAll("\\.+", ""); String s3 = s2.replaceAll("(.)\\1+", "$1"); System.out.println(s3); } private static void demo5() { /* * 疊詞切割: "acyyfgttthjzzzzzko"; * (.)\\1+ //1+代表第一組出現(xiàn)一次到多次 */ String s = "acyyfgttthjzzzzzko"; String regex = "(.)\\1+"; //1+代表第一組出現(xiàn)一次到多次 String[] arr = s.split(regex); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } private static void demo4() { /* * 疊詞 捕獲組 (.)\\1(.)\\2 \\1代表第一組又出現(xiàn)一次 \\2代表第二組又出現(xiàn)一次 * (..)\\1 \\1代表第一組又出現(xiàn)了一次 */ //疊詞 飄飄亮亮,美美麗麗 String regex2 = "(.)\\1(.)\\2"; //\\1代表第一組又出現(xiàn)一次 \\2代表第二組又出現(xiàn)一次 System.out.println("漂漂亮亮".matches(regex2)); //true System.out.println("美美麗麗".matches(regex2)); //false System.out.println("高高興興".matches(regex2)); //true System.out.println("死啦死啦".matches(regex2)); //false System.out.println("----------------------"); //疊詞 漂亮漂亮,美麗美麗 String regex = "(..)\\1"; System.out.println("死啦死啦".matches(regex)); //true System.out.println("高興高興".matches(regex)); //true System.out.println("快快樂樂".matches(regex)); //false } private static void demo3() { /* * replaceAll(regex,replacement) 第一個參數(shù)是正則表達式, 第二個參數(shù)要替換成的字符串 */ String s = "aaoo1ddd3jgjao"; String regex = "\\d"; String s2 = s.replaceFirst(regex, ""); String s3 = s.replaceAll(regex, ""); System.out.println(s2); //aaooddd3jgjao System.out.println(s3); //aaoodddjgjao } private static void demo2() { /* * split(regex) 參數(shù)是正則表達式 返回值是一個數(shù)組 */ String s = "星期一.星期二.星期三.星期四"; String[] array = s.split("\\."); System.out.println(Arrays.toString(array)); } private static void demo1() { /* * 校驗電話號碼 * 1.必須是5-15位數(shù)字 * 2.開頭不能位0 * 3.必須是純數(shù)字 */ String regex = "[1-9]\\d{5,15}"; System.out.println("804360385".matches(regex)); //true System.out.println("430763075439703307503".matches(regex)); //false System.out.println("03534534".matches(regex)); //false } }
總結(jié)
到此這篇關(guān)于正則表達式高級用法之分組使用的文章就介紹到這了,更多相關(guān)正則表達式分組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python如何使用正則表達式識別代碼中的中文、英文和數(shù)字
正則表達式是一種強大的工具,可以幫助我們實現(xiàn)識別代碼中的中文、英文和數(shù)字,本文將分三個部分詳細介紹如何使用正則表達式在 Python 中識別代碼中的中文、英文和數(shù)字,感興趣的朋友跟隨小編一起看看吧2023-06-06javascript正則表達式標記中/g /i /m的用法,以及實例
正則的思想都是一樣的,但是具體的寫法會有所不同,在這里提到的/g,/i,/m在其他的地方也許就不能用了,需要的朋友可以參考下2020-02-02PHP preg_replace() 正則替換所有符合條件的字符串
PHP preg_replace() 正則替換,與Javascript 正則替換不同,PHP preg_replace() 默認就是替換所有符號匹配條件的元素2014-02-02