日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

特殊构造(非捕获总结)

發(fā)布時間:2024/7/23 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 特殊构造(非捕获总结) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

參考:http://blog.chenlb.com/2008/12/java-regular-expression-special-constructs-ornon-capturing-group.html

在 java api 文檔中的正則表達(dá)式關(guān)于特殊構(gòu)造(非捕獲組)的說明看不懂。例如:

(?:X)X,作為非捕獲組
(?idmsux-idmsux)Nothing,但是將匹配標(biāo)志由 on 轉(zhuǎn)為 off
(?idmsux-idmsux:X)X,作為帶有給定標(biāo)志 on - off 的非捕獲組
(?=X)X,通過零寬度的正 lookahead
(?!X)X,通過零寬度的負(fù) lookahead
(?<=X)X,通過零寬度的正 lookbehind
(?<!X)X,通過零寬度的負(fù) lookbehind
(?>X)X,作為獨立的非捕獲組

這些字都說的很抽象。不懂……。還是搜索下去。找到?火龍果 的解釋如下:

以 (? 開頭,) 結(jié)尾的都稱為非捕獲組,在匹配完成后在內(nèi)存中不保留匹配到的字符。

非捕獲組的應(yīng)用比較復(fù)雜,這里只能簡單地說一下它們的意思。

1、(?:X) X,作為非捕獲組
與捕獲組 ( ) 的意思一樣也是將其作為一組進(jìn)行處理,與捕獲組的區(qū)別在于不捕獲匹配的文本,僅僅作為分組。
比如:

要匹配 123123 這個,就可以寫為 (123)\1 使用反向引用,這時只能用捕獲組,在匹配123 后會保留在內(nèi)存中,便于反向引用;

(?:123) 在匹配完后則不會保留反向引用,區(qū)別僅在于此。不保留反向引用可以節(jié)省內(nèi)存,提高效率。

(123)\1等效(?:123)123,代碼示例:

/*** outputs* 模式(123)\1* 123123*/Pattern p = Pattern.compile("(123)\\1");Matcher m = p.matcher("ad123dfe123123grr");System.out.println("模式(123)\\1");while(m.find()){System.out.println(m.group());}/*** outputs* 模式(?:123)123* 123123*/p = Pattern.compile("(?:123)123");m = p.matcher("ad123dfe123123grr");System.out.println("模式(?:123)123");while(m.find()){System.out.println(m.group());}

2、(?idmsux-idmsux)? Nothing,但是將匹配標(biāo)志i d m s u x on - off
用于標(biāo)志匹配,比如:表達(dá)式 (?i)abc(?-i)def 這時,(?i) 打開不區(qū)分大小寫開關(guān),abc 匹配
不區(qū)分大小地進(jìn)行匹配,(?-i) 關(guān)閉標(biāo)志,恢復(fù)不區(qū)分大小寫,這時的 def 只能匹配 def

//(?i)忽略大小寫,這個簡單。但是只適合ASCII字符//當(dāng)有俄文字符——小寫б(大寫Б)л(Л),這時要一起用(?u)p = Pattern.compile("(?i)(?u)sayбл");m = p.matcher("This is a test sayбл hello.\n"+"Wello SayБЛ \nello?");System.out.println("參數(shù)為(?i)(?u)");while(m.find()){System.out.println(m.group());} //單行模式下,.可以匹配任何字符(包括\n)/*** outputs* hello* Wello* \nello*/p = Pattern.compile("(?s).ello");m = p.matcher("This is a test say hello.\n"+ "Wello say \nello?");System.out.println("參數(shù)為(?s)");while(m.find()){System.out.println(m.group());} //多行模式下,\n 或\r\n 作為行的分隔符,不匹配(.)/*** outputs:* hello* Wello*/p = Pattern.compile("(?m).ello");m = p.matcher("This is a test say hello.\n"+ "Wello say \nello?");System.out.println("參數(shù)為(?m)");while(m.find()){System.out.println(m.group());}


//(?d)模式,啟動UNIX行模式,只認(rèn) \n//UNIX 行: \n//WINDOWS 行:\r\n/*** outputs:* ello start:27end:32* ello?start:37end:42*/p = Pattern.compile("(?m)ello.");m = p.matcher("This is a test say hello\r\n"+"Wello say \nello?");System.out.println("參數(shù)為(?d)");while(m.find()){System.out.println( m.group() + "start:" + m.start() + "end:" + m.end() );}//單獨使用(?m)能依據(jù)\n 和\r\n 來分行/*** outputs:* ello* start:20end:25* ello start:27end:32* ello?start:37end:42*/p = Pattern.compile("(?d)(?m)ello.");m = p.matcher("This is a test say hello\r\n"+"Wello say \nello?");System.out.println("參數(shù)為(?d)");while(m.find()){System.out.println( m.group() + "start:" + m.start() + "end:" + m.end() );}//組合使用(?d)(?m)只能依據(jù)\n 來分行

3、(?idmsux-idmsux:X)? X,作為帶有給定標(biāo)志 i d m s u x on - off
與上面的類似,上面的表達(dá)式,可以改寫成為:(?i:abc)def,或者 (?i)abc(?-i:def)

4、(?=X) X,通過零寬度的正 lookahead
5、(?!X) X,通過零寬度的負(fù) lookahead

(?=X) 表示當(dāng)前位置(即字符的縫隙)后面允許出現(xiàn)的字符,比如:表示式 a(?=b),在字符串為
ab 時,可能匹配 a,后面的 (?=b) 表示,a 后面的縫隙,可以看作是零寬度。
(?!X) 表示當(dāng)前位置后面不允許出現(xiàn)的字符

字符掃描,從左到右,所以前瞻即向右看后瞻即向左看

//a(?=b),匹配a前瞻(lookahead)是b;即ab但不捕獲b/*** outputs* a:start=4,end=5* a:start=9,end=10*/p = Pattern.compile("a(?=b)");m = p.matcher("aacdabaaeabdaBh");System.out.println("a(?=b)");while(m.find()){System.out.println(m.group() + ":start=" + m.start() + ",end=" + m.end());} //a(?!b),匹配a前瞻(lookahead)是非b;即a[^b]但不捕獲[^b]/*** outputs* a:start=0,end=1* a:start=1,end=2* a:start=6,end=7* a:start=7,end=8* a:start=12,end=13*/p = Pattern.compile("a(?!b)");m = p.matcher("aacdabaaeabdaBh");System.out.println("a(?!b)");while(m.find()){System.out.println(m.group() + ":start=" + m.start() + ",end=" + m.end());}

6、(? <=X) X,通過零寬度的正 lookbehind
7、(? <!X) X,通過零寬度的負(fù) lookbehind

這兩個與上面兩個類似,上面兩個是向后看,這個是向前看

//(?<=b)a,匹配a后瞻(lookbehind)是b;即ba但不捕獲b/*** outputs* a:start=6,end=7*/p = Pattern.compile("(?<=b)a");m = p.matcher("aacdabaaeabdaBh");System.out.println("(?<=b)a");while(m.find()){System.out.println(m.group() + ":start=" + m.start() + ",end=" + m.end());} //(?<!b)a,匹配a后瞻(lookbehind)是非b;即[^b]a但不捕獲[^b]/*** outputs* a:start=0,end=1* a:start=1,end=2* a:start=4,end=5* a:start=7,end=8* a:start=9,end=10* a:start=12,end=13*/p = Pattern.compile("(?<!b)a");m = p.matcher("aacdabaaeabdaBh");System.out.println("(?<!b)a");while(m.find()){System.out.println(m.group() + ":start=" + m.start() + ",end=" + m.end());}

8、(?>X) X,作為獨立的非捕獲組
匹配成功不進(jìn)行回溯,這個比較復(fù)雜,也侵占量詞“+”可以通用,比如:\d++ 可以寫為 (?>\d+)。

//(?>x)不回溯的匹配,性能優(yōu)化/*** outputs* integer:start=5,end=12* insert:start=17,end=23* in:start=27,end=29*/p = Pattern.compile("\\b(?>integer|insert|in)\\b");m = p.matcher("test integer and insert of in it");System.out.println("\\b(?>integer|insert|in)\\b");while(m.find()){System.out.println(m.group() + ":start=" + m.start() + ",end=" + m.end());} // 換了個順序,結(jié)果大不一樣!
/*** outputs* in:start=27,end=29*/p = Pattern.compile("\\b(?>in|integer|insert)\\b");m = p.matcher("test integer and insert of in it");System.out.println("\\b(?>in|integer|insert)\\b");while(m.find()){System.out.println(m.group() + ":start=" + m.start() + ",end=" + m.end());}

還沒搞懂,為什么換個順序后結(jié)果就不同了,反正別人建議是:長的放前面,短的放后面。至于原因嘛,以后懂了再說。












總結(jié)

以上是生活随笔為你收集整理的特殊构造(非捕获总结)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。