Java正則表達(dá)式API字符類
一、Predefined字符類
Java正則表達(dá)式API也接受預(yù)定義的字符類。上面的一些字符類可以用更短的形式表示,盡管這會(huì)降低代碼的直觀性。這個(gè)正則表達(dá)式的Java版本的一個(gè)特殊方面是轉(zhuǎn)義字符。
正如我們將看到的,大多數(shù)字符都以反斜杠開(kāi)頭,這在Java中有特殊的意義。對(duì)于要由模式類編譯的這些,必須轉(zhuǎn)義前導(dǎo)反斜杠,即.\d
變?yōu)?code>\\d。
匹配的數(shù)字,相當(dāng)于[0-9]
:
@Test public void givenDigits_whenMatches_thenCorrect() { int matches = runTest("\\d", "123"); assertEquals(matches, 3); }
匹配非數(shù)字,相當(dāng)于[^0-9]
:
@Test public void givenNonDigits_whenMatches_thenCorrect() { int mathces = runTest("\\D", "a6c"); assertEquals(matches, 2); }
匹配空白:
@Test public void givenWhiteSpace_whenMatches_thenCorrect() { int matches = runTest("\\s", "a c"); assertEquals(matches, 1); }
匹配非空白:
@Test public void givenNonWhiteSpace_whenMatches_thenCorrect() { int matches = runTest("\\S", "a c"); assertEquals(matches, 2); }
匹配一個(gè)單詞字符,相當(dāng)于[a-zA-Z_0-9]
:
@Test public void givenWordCharacter_whenMatches_thenCorrect() { int matches = runTest("\\w", "hi!"); assertEquals(matches, 2); }
匹配非單詞字符:
@Test public void givenNonWordCharacter_whenMatches_thenCorrect() { int matches = runTest("\\W", "hi!"); assertEquals(matches, 1); }
二、Quantifiers
Java正則表達(dá)式API還允許我們使用Quantifiers。通過(guò)指定匹配的出現(xiàn)次數(shù),我們可以進(jìn)一步調(diào)整匹配的行為。
要匹配零次或一次文本,我們使用?
量詞:
@Test public void givenZeroOrOneQuantifier_whenMatches_thenCorrect() { int matches = runTest("\\a?", "hi"); assertEquals(matches, 3); }
或者,我們可以使用大括號(hào)語(yǔ)法,Java regex API也支持這種語(yǔ)法:
@Test public void givenZeroOrOneQuantifier_whenMatches_thenCorrect2() { int matches = runTest("\\a{0,1}", "hi"); assertEquals(matches, 3); }
本例介紹了零長(zhǎng)度匹配的概念。碰巧的是,如果一個(gè)量詞的匹配閾值為零,它總是匹配文本中的所有內(nèi)容,包括每個(gè)輸入末尾的一個(gè)空字符串。這意味著即使輸入為空,它也將返回一個(gè)零長(zhǎng)度匹配。
這就解釋了為什么在上面的示例中,盡管字符串長(zhǎng)度為2,但我們?nèi)缘玫?個(gè)匹配項(xiàng)。第三個(gè)匹配項(xiàng)是長(zhǎng)度為零的空字符串。
為了匹配零次或無(wú)限次的文本,我們使用*
量詞,它與?:
@Test public void givenZeroOrManyQuantifier_whenMatches_thenCorrect() { int matches = runTest("\\a*", "hi"); assertEquals(matches, 3); }
支持的替代方案:
@Test public void givenZeroOrManyQuantifier_whenMatches_thenCorrect2() { int matches = runTest("\\a{0,}", "hi"); assertEquals(matches, 3); }
差異量詞為+,匹配閾值為1。如果所需的字符串根本不出現(xiàn),則將不存在匹配項(xiàng),甚至不存在長(zhǎng)度為零的字符串:
@Test public void givenOneOrManyQuantifier_whenMatches_thenCorrect() { int matches = runTest("\\a+", "hi"); assertFalse(matches); }
支持的替代方案:
@Test public void givenOneOrManyQuantifier_whenMatches_thenCorrect2() { int matches = runTest("\\a{1,}", "hi"); assertFalse(matches); }
正如在Perl和其他語(yǔ)言中一樣,大括號(hào)語(yǔ)法可用于多次匹配給定文本:
@Test public void givenBraceQuantifier_whenMatches_thenCorrect() { int matches = runTest("a{3}", "aaaaaa"); assertEquals(matches, 2); }
在上面的例子中,我們得到了兩個(gè)匹配項(xiàng),因?yàn)橹挥挟?dāng)a在一行中出現(xiàn)三次時(shí),才會(huì)出現(xiàn)匹配項(xiàng)。但是,在下一次測(cè)試中,我們不會(huì)得到匹配,因?yàn)槲谋驹谝恍兄兄怀霈F(xiàn)兩次:
@Test public void givenBraceQuantifier_whenFailsToMatch_thenCorrect() { int matches = runTest("a{3}", "aa"); assertFalse(matches > 0); }
當(dāng)我們?cè)诖罄ㄌ?hào)中使用范圍時(shí),匹配將是貪婪的,從范圍的高端匹配:
@Test public void givenBraceQuantifierWithRange_whenMatches_thenCorrect() { int matches = runTest("a{2,3}", "aaaa"); assertEquals(matches, 1); }
我們已經(jīng)指定了至少兩次但不超過(guò)三次,所以我們得到一個(gè)匹配,匹配者看到一個(gè)aaa
和一個(gè)無(wú)法匹配的a
。
然而,API允許我們指定一種懶惰或不情愿的方法,以便匹配器可以從范圍的低端開(kāi)始,在這種情況下,匹配兩個(gè)匹配項(xiàng)aa和aa:
@Test public void givenBraceQuantifierWithRange_whenMatchesLazily_thenCorrect() { int matches = runTest("a{2,3}?", "aaaa"); assertEquals(matches, 2); }
三、Capturing Groups
API還允許我們通過(guò)Capturing Groups將多個(gè)角色視為一個(gè)單元。它會(huì)將數(shù)字附加到Capturing Groups,并允許使用這些數(shù)字進(jìn)行反向引用。
在本節(jié)中,我們將看到一些關(guān)于如何在Java正則表達(dá)式API中使用Capturing Groups的示例。
讓我們使用一個(gè)僅當(dāng)輸入文本包含兩個(gè)相鄰數(shù)字時(shí)才匹配的Capturing Groups:
@Test public void givenCapturingGroup_whenMatches_thenCorrect() { int maches = runTest("(\\d\\d)", "12"); assertEquals(matches, 1); }
上面匹配的數(shù)字是1,使用back
引用告訴匹配者我們想要匹配文本匹配部分的另一個(gè)匹配項(xiàng)。這樣做,而不是:
@Test public void givenCapturingGroup_whenMatches_thenCorrect2() { int matches = runTest("(\\d\\d)", "1212"); assertEquals(matches, 2); }
如果輸入有兩個(gè)單獨(dú)的匹配項(xiàng),我們可以有一個(gè)匹配項(xiàng),但使用反向引用傳播相同的正則表達(dá)式匹配項(xiàng)以跨越輸入的整個(gè)長(zhǎng)度:
@Test public void givenCapturingGroup_whenMatchesWithBackReference_ thenCorrect() { int matches = runTest("(\\d\\d)\\1", "1212"); assertEquals(matches, 1); }
我們必須重復(fù)正則表達(dá)式,而無(wú)需反向引用,才能獲得相同的結(jié)果:
@Test public void givenCapturingGroup_whenMatches_thenCorrect3() { int matches = runTest("(\\d\\d)(\\d\\d)", "1212"); assertEquals(matches, 1); }
類似地,對(duì)于任何其他重復(fù)次數(shù),反向引用可以使匹配者將輸入視為單個(gè)匹配:
@Test public void givenCapturingGroup_whenMatchesWithBackReference_ thenCorrect2() { int matches = runTest("(\\d\\d)\\1\\1\\1", "12121212"); assertEquals(matches, 1); }
但如果你甚至改變了最后一個(gè)數(shù)字,匹配就會(huì)失?。?/strong>
@Test public void givenCapturingGroupAndWrongInput_ whenMatchFailsWithBackReference_thenCorrect() { int matches = runTest("(\\d\\d)\\1", "1213"); assertFalse(matches > 0); }
重要的是不要忘記轉(zhuǎn)義反斜杠,這在Java語(yǔ)法中至關(guān)重要。
到此這篇關(guān)于Java正則表達(dá)式API字符類的文章就介紹到這了,更多相關(guān)Java正則表達(dá)式 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring整合redis緩存并以注解(@Cacheable、@CachePut、@CacheEvict)形式使用
本篇文章主要介紹了spring整合redis緩存并以注解(@Cacheable、@CachePut、@CacheEvict)形式使用,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-04-04JAVA多線程的使用場(chǎng)景與注意事項(xiàng)總結(jié)
這篇文章主要給大家介紹了關(guān)于JAVA多線程的使用場(chǎng)景與注意事項(xiàng)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03java使用RandomAccessFile類基于指針讀寫文件實(shí)例代碼
這篇文章主要介紹了java使用RandomAccessFile類基于指針讀寫文件實(shí)例代碼,具有一定參考價(jià)值,需要的朋友可以了解下。2017-10-10淺談在Java中使用Callable、Future進(jìn)行并行編程
這篇文章主要介紹了淺談在Java中使用Callable、Future進(jìn)行并行編程,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12詳解Spring boot+CXF開(kāi)發(fā)WebService Demo
這篇文章主要介紹了詳解Spring boot+CXF開(kāi)發(fā)WebService Demo,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05SpringBoot中Mybatis + Druid 數(shù)據(jù)訪問(wèn)的詳細(xì)過(guò)程
Spring Boot 底層都是采用 SpringData 的方式進(jìn)行統(tǒng)一處理各種數(shù)據(jù)庫(kù),SpringData也是Spring中與SpringBoot、SpringCloud 等齊名的知名項(xiàng)目,下面看下SpringBoot Mybatis Druid數(shù)據(jù)訪問(wèn)的詳細(xì)過(guò)程,感興趣的朋友一起看看吧2021-11-11Java后臺(tái)防止客戶端重復(fù)請(qǐng)求、提交表單實(shí)現(xiàn)原理
這篇文章主要介紹了Java后臺(tái)防止客戶端重復(fù)請(qǐng)求、提交表單實(shí)現(xiàn)原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12