當我開始使用Java時,正則表達式對我來說是一場噩夢。 本教程旨在幫助您掌握Java正則表達式,并讓我定期返回以刷新我的正則表達式學習。
什么是正則表達式?
正則表達式定義字符串的模式。 正則表達式可用于搜索,編輯或處理文本。 正則表達式不是特定于語言的,但是每種語言的正則表達式略有不同。 Java正則表達式與Perl最相似。
Java正則表達式類存在于java.util.regex軟件包中,該軟件包包含三個類: Pattern , Matcher和PatternSyntaxException 。
1.模式對象是正則表達式的編譯版本。 它沒有任何公共構造函數,我們使用其公共靜態方法compile通過傳遞正則表達式參數來創建模式對象。
2. Matcher是將輸入的字符串模式與創建的模式對象進行匹配的正則表達式引擎對象。 此類沒有任何公共構造函數,并且我們使用模式對象匹配器方法(將輸入String作為參數)來獲得Matcher對象。 然后,我們使用matchs方法根據輸入的String是否匹配正則表達式模式返回布爾結果。
3.如果正則表達式語法不正確,則會引發PatternSyntaxException。
讓我們通過一個簡單的示例查看所有這些類的作用:
package com.journaldev.util;import java.util.regex.*;public class PatternExample {public static void main(String[] args) {Pattern pattern = Pattern.compile('.xx.');Matcher matcher = pattern.matcher('MxxY');System.out.println('Input String matches regex - '+matcher.matches());// bad regular expressionpattern = Pattern.compile('*xx*');}}
上面程序的輸出是:
Input String matches regex - true
Exception in thread 'main' java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
*xx*
^at java.util.regex.Pattern.error(Pattern.java:1924)at java.util.regex.Pattern.sequence(Pattern.java:2090)at java.util.regex.Pattern.expr(Pattern.java:1964)at java.util.regex.Pattern.compile(Pattern.java:1665)at java.util.regex.Pattern.(Pattern.java:1337)at java.util.regex.Pattern.compile(Pattern.java:1022)at com.journaldev.util.PatternExample.main(PatternExample.java:13)
由于正則表達式圍繞String展開,因此Java 1.4中對String類進行了擴展,以提供進行模式匹配的match方法。 在內部,它使用Pattern和Matcher類進行處理,但是顯然,它減少了代碼行。
模式類還包含matches方法,該方法以正則表達式和輸入String作為參數,并在匹配它們后返回布爾結果。
因此,以下代碼可以很好地將輸入String與正則表達式匹配。
String str = 'bbb';System.out.println('Using String matches method: '+str.matches('.bb'));System.out.println('Using Pattern matches method: '+Pattern.matches('.bb', str));
因此,如果您只需要檢查輸入的String是否與模式匹配,則應使用簡單的String Match方法來節省時間。 僅在需要操縱輸入String或需要重用模式時,才使用Pattern和Matches類。
請注意,由正則表達式定義的模式從左到右應用于字符串,并且一旦在匹配項中使用了源字符,就無法重用它。
例如,正則表達式“ 121”將匹配“ 31212142121”的次數是“ _121____121”的兩倍。
正則表達式常見的匹配符號
正則表達式 | 描述 | 例 |
。 | 匹配任何單個符號,包括所有內容 | (“ ..”,“ a%”)– true(“ ..”,“。a”)– true (“ ..”,“ a”)–否 |
^ xxx | 在行首匹配xxx正則表達式 | (“ ^ ac”,“ abcd”)– true(“ ^ a”,“ a”)– true (“ ^ a”,“ ac”)–否 |
xxx $ | 在行尾匹配正則表達式xxx | (“ .cd $”,“ abcd”)–真(“ a $”,“ a”)–真 (“ a $”,“ aca”)–否 |
[abc] | 可以匹配字母a,b或c。 []被稱為字符類。 | (“ ^ [abc] d。”,“ ad9”)–正確(“ [ab] .d $”,“壞”)–正確 (“ [ab] x”,“ cx”)–否 |
[abc] [12] | 可以匹配a,b或c,然后匹配1或2 | (“ [ab] [12]。”,“ a2#”)– true(“ [ab] .. [12]”,“ acd2”)– true (“ [ab] [12]”,“ c2”)–否 |
[^ abc] | 當^是[]中的第一個字符時,它會否定模式,匹配除a,b或c之外的任何其他字符 | (“ [[^ ab] [^ 12]。”,“ c3#”)–真(“ [[^ ab] .. [^ 12]”,“ xcd3”)–真 (“ [^ ab] [^ 12]”,“ c2”)–否 |
[a-e1-8] | 匹配范圍從a到e或1到8 | (“ [a-e1-3]”,“ d#”)–真(“ [a-e1-3]”,“ 2”)-真 (“ [a-e1-3]”,“ f2”)–否 |
xx | yy | 匹配正則表達式xx或yy | (“ x。| y”,“ xa”)– true(“ x。| y”,“ y”) (“ x。| y”,“ yz”)–否 |
Java正則表達式元字符
正則表達式 | 描述 |
\ d | 任何數字,少于[0-9] |
\ D | 任何非數字,是[^ 0-9]的縮寫 |
\ s | 任何空格字符,是[\ t \ n \ x0B \ f \ r]的縮寫 |
\ S | 任何非空白字符,是[^ \ s]的縮寫 |
\ w | 任何文字字符,是[a-zA-Z_0-9]的縮寫 |
\ W | 任何非單詞字符,是[^ \ w]的縮寫 |
\ b | 單詞邊界 |
\ B | 非單詞邊界 |
在正則表達式中有兩種方法可以將元字符用作普通字符。
- 在元字符之前加一個反斜杠(\)。
- 保持元字符在\ Q(以引號開頭)和\ E(以引號結尾)之內。
正則表達式量詞
量詞指定要匹配的字符的出現次數。
正則表達式 | 描述 |
X? | x發生一次或根本不發生 |
X* | X出現零次或多次 |
X + | X發生一次或多次 |
X {n} | X正好發生n次 |
X {n,} | X出現n次或更多次 |
X {n,m} | X發生至少n次但不超過m次 |
量詞也可以與字符類和捕獲組一起使用。
例如,[abc] +表示a,b或c一次或多次。
(abc)+表示“ abc”組再出現一次。 我們現在將討論捕獲組 。
正則表達式捕獲組
捕獲組用于將多個字符視為一個單元。 您可以使用()創建一個組。 輸入String與捕獲組匹配的部分被保存到內存中,可以使用Backreference進行調用。
您可以使用matcher.groupCount方法找出正則表達式模式中的捕獲組數。 例如在((a)(bc))中包含3個捕獲組; ((a)(bc)),(a)和(bc)。
您可以在正則表達式中使用反引號 (\),然后再調用要調用的組數。
捕獲組和反向引用可能會造成混淆,因此讓我們通過一個示例來理解它。
System.out.println(Pattern.matches('(\\w\\d)\\1', 'a2a2')); //trueSystem.out.println(Pattern.matches('(\\w\\d)\\1', 'a2b2')); //falseSystem.out.println(Pattern.matches('(AB)(B\\d)\\2\\1', 'ABB2B2AB')); //trueSystem.out.println(Pattern.matches('(AB)(B\\d)\\2\\1', 'ABB2B3AB')); //false
在第一個示例中,在運行時,第一個捕獲組是(\ w \ d),當與輸入字符串“ a2a2”匹配并保存在內存中時,其計算結果為“ a2”。 因此\ 1指的是“ a2”,因此它返回true。 由于相同的原因,第二條語句打印為false。
嘗試自己了解語句3和4的這種情況。
現在,我們將研究一些重要的Pattern和Matcher類方法。
我們可以創建帶有標志的Pattern對象。 例如模式。 CASE_INSENSITIVE啟用不區分大小寫的匹配。
模式類還提供了類似于String類split()方法的split(String) 。
模式類toString()方法返回從中編譯此模式的正則表達式String。
Matcher類具有start()和end()索引方法,這些方法精確顯示在輸入字符串中找到匹配項的位置。
Matcher類還提供String操作方法replaceAll(String替換)和replaceFirst(String替換) 。
現在,我們將通過一個簡單的java類看到這些常用功能:
package com.journaldev.util;import java.util.regex.Matcher;
import java.util.regex.Pattern;public class RegexExamples {public static void main(String[] args) {// using pattern with flagsPattern pattern = Pattern.compile('ab', Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher('ABcabdAb');// using Matcher find(), group(), start() and end() methodswhile (matcher.find()) {System.out.println('Found the text \'' + matcher.group()+ '\' starting at ' + matcher.start()+ ' index and ending at index ' + matcher.end());}// using Pattern split() methodpattern = Pattern.compile('\\W');String[] words = pattern.split('one@two#three:four$five');for (String s : words) {System.out.println('Split using Pattern.split(): ' + s);}// using Matcher.replaceFirst() and replaceAll() methodspattern = Pattern.compile('1*2');matcher = pattern.matcher('11234512678');System.out.println('Using replaceAll: ' + matcher.replaceAll('_'));System.out.println('Using replaceFirst: ' + matcher.replaceFirst('_'));}}
上面程序的輸出是:
Found the text 'AB' starting at 0 index and ending at index 2
Found the text 'ab' starting at 3 index and ending at index 5
Found the text 'Ab' starting at 6 index and ending at index 8
Split using Pattern.split(): one
Split using Pattern.split(): two
Split using Pattern.split(): three
Split using Pattern.split(): four
Split using Pattern.split(): five
Using replaceAll: _345_678
Using replaceFirst: _34512678
正則表達式是Java面試問題的領域之一,在接下來的幾篇文章中,我將提供一些實際示例。
參考: 開發人員食譜博客上的JCG合作伙伴 Pankaj Kumar的Java正則表達式示例教程 。
翻譯自: https://www.javacodegeeks.com/2012/11/java-regular-expression-tutorial-with-examples.html