java正则表达式 and_Java正则表达式详解
原標題:Java正則表達式詳解
Java 提供了功能強大的正則表達式API,在java.util.regex 包下。本教程介紹如何使用正則表達式API。
正則表達式
一個正則表達式是一個用于文本搜索的文本模式。換句話說,在文本中搜索出現的模式。例如,你可以用正則表達式搜索網頁中的郵箱地址或超鏈接。
正則表達式示例
下面是一個簡單的Java正則表達式的例子,用于在文本中搜索 http://
Stringtext= "This is the text to be searched "+ "for occurrences of the http:// pattern."; Stringpattern = ".*http://.*"; booleanmatches = Pattern.matches(pattern, text); System.out.println( "matches = "+ matches);
示例代碼實際上沒有檢測找到的 http:// 是否是一個合法超鏈接的一部分,如包含域名和后綴(.com,.net 等等)。代碼只是簡單的查找字符串 http:// 是否出現。
Java6 中關于正則表達式的API
本教程介紹了Java6 中關于正則表達式的API。
Pattern (java.util.regex.Pattern)
類 java.util.regex.Pattern 簡稱 Pattern, 是Java正則表達式API中的主要入口,無論何時,需要使用正則表達式,從Pattern 類開始
Pattern.matches()
檢查一個正則表達式的模式是否匹配一段文本的最直接方法是調用靜態方法Pattern.matches(),示例如下:
Stringtext= "This is the text to be searched "+ "for occurrences of the pattern."; Stringpattern = ".*is.*"; booleanmatches = Pattern.matches(pattern, text); System.out.println( "matches = "+ matches);
上面代碼在變量 text 中查找單詞 “is” 是否出現,允許”is” 前后包含 0或多個字符(由 .* 指定)
Pattern.matches() 方法適用于檢查 一個模式在一個文本中出現一次的情況,或適用于Pattern類的默認設置。
如果需要匹配多次出現,甚至輸出不同的匹配文本,或者只是需要非默認設置。需要通過Pattern.compile() 方法得到一個Pattern 實例。
Pattern.compile()
如果需要匹配一個正則表達式在文本中多次出現,需要通過Pattern.compile() 方法創建一個Pattern對象。示例如下
Stringtext = "This is the text to be searched "+ "for occurrences of the http:// pattern."; StringpatternString = ".*http://.*"; Patternpattern = Pattern.compile(patternString);
可以在Compile 方法中,指定一個特殊標志:
Patternpattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
Pattern 類包含多個標志(int 類型),這些標志可以控制Pattern 匹配模式的方式。上面代碼中的標志使模式匹配是忽略大小寫
Pattern.matcher()
一旦獲得了Pattern對象,接著可以獲得Matcher對象。Matcher 示例用于匹配文本中的模式.示例如下
Matcher matcher= pattern.matcher(text);
Matcher類有一個matches()方法,可以檢查文本是否匹配模式。以下是關于Matcher的一個完整例子
String text = "This is the text to be searched "+ "for occurrences of the http:// pattern.";String patternString = ".*http://.*";Pattern pattern = Pattern .compile(patternString, Pattern .CASE_INSENSITIVE) ;Matcher matcher = pattern .matcher(text) ;boolean matches = matcher .matches() ;System .out.println( "matches = "+ matches) ;
Pattern.split()
Pattern 類的 split()方法,可以用正則表達式作為分隔符,把文本分割為String類型的數組。示例:
Stringtext = "A sep Text sep With sep Many sep Separators"; StringpatternString = "sep"; Pattern pattern = Pattern.compile(patternString); String[] split= pattern. split(text); System.out.println( "split.length = "+ split.length); for( Stringelement : split){ System.out.println( "element = "+ element); }
上例中把text 文本分割為一個包含5個字符串的數組。
Pattern.pattern()
Pattern 類的 pattern 返回用于創建Pattern 對象的正則表達式,示例:
StringpatternString = "sep"; Patternpattern = Pattern.compile(patternString); Stringpattern2 = pattern.pattern();
上面代碼中 pattern2 值為sep ,與patternString 變量相同。
Matcher (java.util.regex.Matcher)
java.util.regex.Matcher 類用于匹配一段文本中多次出現一個正則表達式,Matcher 也適用于多文本中匹配同一個正則表達式。
Matcher 有很多有用的方法,詳細請參考官方JavaDoc。這里只介紹核心方法。
以下代碼演示如何使用Matcher
Stringtext= "This is the text to be searched "+ "for occurrences of the http:// pattern."; StringpatternString = ".*http://.*"; Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher( text); booleanmatches = matcher.matches();
首先創建一個Pattern,然后得到Matcher ,調用matches() 方法,返回true 表示模式匹配,返回false表示不匹配。
可以用Matcher 做更多的事。
創建Matcher
通過Pattern 的matcher() 方法創建一個Matcher。
Stringtext = "This is the text to be searched "+ "for occurrences of the http:// pattern."; StringpatternString = ".*http://.*"; Patternpattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(text);
matches()
Matcher 類的 matches() 方法用于在文本中匹配正則表達式
boolean matches= matcher. matches();
如果文本匹配正則表達式,matches() 方法返回true。否則返回false。
matches() 方法不能用于查找正則表達式多次出現。如果需要,請使用find(), start() 和 end() 方法。
lookingAt()
lookingAt() 與matches() 方法類似,最大的不同是,lookingAt()方法對文本的開頭匹配正則表達式;而
matches() 對整個文本匹配正則表達式。換句話說,如果正則表達式匹配文本開頭而不匹配整個文本,lookingAt() 返回true,而matches() 返回false。 示例:
String text = "This is the text to be searched "+ "for occurrences of the http:// pattern.";String patternString = "This is the";Pattern pattern = Pattern .compile(patternString, Pattern .CASE_INSENSITIVE) ;Matcher matcher = pattern .matcher(text) ;System .out.println( "lookingAt = "+ matcher .lookingAt()) ;System .out.println( "matches = "+ matcher .matches()) ;
上面的例子分別對文本開頭和整個文本匹配正則表達式 “this is the”. 匹配文本開頭的方法(lookingAt()) 返回true。
對整個文本匹配正則表達式的方法 (matches()) 返回false,因為 整個文本包含多余的字符,而 正則表達式要求文本精確匹配”this is the”,前后又不能有額外字符。
find() + start() + end()
find() 方法用于在文本中查找出現的正則表達式,文本是創建Matcher時,通過 Pattern.matcher(text) 方法傳入的。如果在文本中多次匹配,find() 方法返回第一個,之后每次調用 find() 都會返回下一個。
start() 和 end() 返回每次匹配的字串在整個文本中的開始和結束位置。實際上, end() 返回的是字符串末尾的后一位,這樣,可以在把 start() 和 end() 的返回值直接用在String.substring() 里。
/** * Java學習交流QQ群:589809992 我們一起學Java! */String text = "This is the text which is to be searched "+ "for occurrences of the word 'is'."; String patternString = "is"; Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(text); intcount = 0; while(matcher.find()) { count++; System.out.println( "found: "+ count + " : "+ matcher.start() + " - "+ matcher.end()); }
這個例子在文本中找到模式 “is” 4次,輸出如下:
found: 1 : 2 - 4found: 2 : 5 - 7found: 3 : 23 - 25found: 4 : 70 - 72
reset()
reset() 方法會重置Matcher 內部的 匹配狀態。當find() 方法開始匹配時,Matcher 內部會記錄截至當前查找的距離。調用 reset() 會重新從文本開頭查找。
也可以調用 reset(CharSequence) 方法. 這個方法重置Matcher,同時把一個新的字符串作為參數傳入,用于代替創建 Matcher 的原始字符串。
group()
假設想在一個文本中查找URL鏈接,并且想把找到的鏈接提取出來。當然可以通過 start()和 end()方法完成。但是用group()方法更容易些。
分組在正則表達式中用括號表示,例如:
(John)
此正則表達式匹配John, 括號不屬于要匹配的文本。括號定義了一個分組。當正則表達式匹配到文本后,可以訪問分組內的部分。
使用group(int groupNo) 方法訪問一個分組。一個正則表達式可以有多個分組。每個分組由一對括號標記。想要訪問正則表達式中某分組匹配的文本,可以把分組編號傳入 group(int groupNo)方法。
group(0) 表示整個正則表達式,要獲得一個有括號標記的分組,分組編號應該從1開始計算。
String text = "John writes about this, and John writes about that,"+ " and John writes about everything. ";String patternString1 = "(John)";Pattern pattern = Pattern .compile(patternString1) ;Matcher matcher = pattern .matcher(text) ;while(matcher .find()) { System .out.println( "found: "+ matcher .group( 1)) ;}
以上代碼在文本中搜索單詞John.從每個匹配文本中,提取分組1,就是由括號標記的部分。輸出如下
found: Johnfound: Johnfound: John
多分組
上面提到,一個正則表達式可以有多個分組,例如:
(John)(.+?)
這個表達式匹配文本”John” 后跟一個空格,然后跟1個或多個字符,最后跟一個空格。你可能看不到最后的空格。
這個表達式包括一些字符有特別意義。字符 點 . 表示任意字符。 字符 + 表示出現一個或多個,和. 在一起表示 任何字符,出現一次或多次。字符? 表示 匹配盡可能短的文本。
完整代碼如下
/** * Java學習交流QQ群:589809992 我們一起學Java! */String text = "John writes about this, and John Doe writes about that,"+ " and John Wayne writes about everything."; String patternString1 = "(John) (.+?) "; Pattern pattern = Pattern.compile(patternString1); Matcher matcher = pattern.matcher(text); while(matcher.find()) { System.out.println( "found: "+ matcher.group( 1) + " "+ matcher.group( 2)); }
注意代碼中引用分組的方式。代碼輸出如下
found: John writesfound: John Doefound: John Wayne
嵌套分組
在正則表達式中分組可以嵌套分組,例如
((John)(.+?))
這是之前的例子,現在放在一個大分組里.(表達式末尾有一個空格)。
當遇到嵌套分組時, 分組編號是由左括號的順序確定的。上例中,分組1 是那個大分組。分組2 是包括John的分組,分組3 是包括 .+? 的分組。當需要通過groups(int groupNo) 引用分組時,了解這些非常重要。
以下代碼演示如何使用嵌套分組
String text = "John writes about this, and John Doe writes about that,"+ " and John Wayne writes about everything.";String patternString1 = "((John) (.+?)) ";Pattern pattern = Pattern .compile(patternString1) ;Matcher matcher = pattern .matcher(text) ;while(matcher .find()) { System .out.println( "found: ") ;}
輸出如下
found: found: found:
replaceAll() + replaceFirst()
replaceAll() 和 replaceFirst() 方法可以用于替換Matcher搜索字符串中的一部分。replaceAll() 方法替換全部匹配的正則表達式,replaceFirst() 只替換第一個匹配的。
在處理之前,Matcher 會先重置。所以這里的匹配表達式從文本開頭開始計算。
示例如下
/** * Java學習交流QQ群:589809992 我們一起學Java! */String text = "John writes about this, and John Doe writes about that,"+ " and John Wayne writes about everything."; String patternString1 = "((John) (.+?)) "; Pattern pattern = Pattern.compile(patternString1); Matcher matcher = pattern.matcher(text); String replaceAll = matcher.replaceAll( "Joe Blocks "); System.out.println( "replaceAll = "+ replaceAll); String replaceFirst = matcher.replaceFirst( "Joe Blocks "); System.out.println( "replaceFirst = "+ replaceFirst);
輸出如下
replaceAll = Joe Blocks aboutthis, andJoe Blocks writes aboutthat, andJoe Blocks writes abouteverything. replaceFirst = Joe Blocks aboutthis, andJohn Doe writes aboutthat, andJohn Wayne writes abouteverything.
輸出中的換行和縮進是為了可讀而增加的。
注意第1個字符串中所有出現 John 后跟一個單詞 的地方,都被替換為 Joe Blocks 。第2個字符串中,只有第一個出現的被替換。
appendReplacement() + appendTail()
appendReplacement() 和 appendTail() 方法用于替換輸入文本中的字符串短語,同時把替換后的字符串附加到一個 StringBuffer 中。
當find() 方法找到一個匹配項時,可以調用 appendReplacement() 方法,這會導致輸入字符串被增加到StringBuffer 中,而且匹配文本被替換。 從上一個匹配文本結尾處開始,直到本次匹配文本會被拷貝。
appendReplacement() 會記錄拷貝StringBuffer 中的內容,可以持續調用find(),直到沒有匹配項。
直到最后一個匹配項目,輸入文本中剩余一部分沒有拷貝到 StringBuffer. 這部分文本是從最后一個匹配項結尾,到文本末尾部分。通過調用 appendTail() 方法,可以把這部分內容拷貝到 StringBuffer 中.
/** * Java學習交流QQ群:589809992 我們一起學Java! */String text = "John writes about this, and John Doe writes about that,"+ " and John Wayne writes about everything."; String patternString1 = "((John) (.+?)) "; Pattern pattern = Pattern.compile(patternString1); Matcher matcher = pattern.matcher(text); StringBuffer stringBuffer = newStringBuffer(); while(matcher.find()){ matcher.appendReplacement(stringBuffer, "Joe Blocks "); System.out.println(stringBuffer.toString()); } matcher.appendTail(stringBuffer); System.out.println(stringBuffer.toString());
注意我們在while循環中調用appendReplacement() 方法。在循環完畢后調用appendTail()。 代碼輸出如下:
Joe Blocks Joe Blocks aboutthis, andJoe Blocks Joe Blocks aboutthis, andJoe Blocks writes aboutthat, andJoe Blocks Joe Blocks aboutthis, andJoe Blocks writes aboutthat, andJoe Blocks writes abouteverything.Java 正則表達式語法
為了更有效的使用正則表達式,需要了解正則表達式語法。正則表達式語法很復雜,可以寫出非常高級的表達式。只有通過大量的練習才能掌握這些語法規則。
本篇文字,我們將通過例子了解正則表達式語法的基礎部分。介紹重點將會放在為了使用正則表達式所需要了解的核心概念,不會涉及過多的細節。詳細解釋,參見 Java DOC 中的 Pattern 類.
基本語法
在介紹高級功能前,我們先快速瀏覽下正則表達式的基本語法。
字符
是正則表達式中最經常使用的的一個表達式,作用是簡單的匹配一個確定的字符。例如:
John
這個簡單的表達式將會在一個輸入文本中匹配John文本。
可以在表達式中使用任意英文字符。也可以使用字符對于的8進制,16進制或unicode編碼表示。例如:
101 \x41 \u0041
以上3個表達式 都表示大寫字符A。第一個是8進制編碼(101),第2個是16進制編碼(41),第3個是unicode編碼(0041).
字符分類
字符分類是一種結構,可以針對多個字符匹配而不只是一個字符。換句話說,一個字符分類匹配輸入文本中的一個字符,對應字符分類中多個允許字符。例如,你想匹配字符 a,b 或c,表達式如下:
[abc]
用一對方括號[] 表示字符分類。方括號本身并不是要匹配的一部分。
可以用字符分類完成很多事。例如想要匹配單詞John,首字母可以為大寫和小寫J.
[Jj]ohn
字符分類[Jj] 匹配J或j,剩余的 ohn 會準確匹配字符ohn.
預定義字符分類
正則表達式中有一些預定義的字符分類可以使用。例如, \d 表示任意數字, \s 表示任意空白字符,\w 表示任意單詞字符。
預定義字符分類不需要括在方括號里,當然也可以組合使用
\d[\d\s]
第1個匹配任意數字,第2個匹配任意數字或空白符。
完整的預定義字符分類列表,在本文最后列出。
邊界匹配
正則表達式支持匹配邊界,例如單詞邊界,文本的開頭或末尾。例如,\w 匹配一個單詞,^匹配行首,$ 匹配行尾。
^This is asingle line$
上面的表達式匹配一行文本,只有文本 This is a single line。注意其中的行首和行尾標志,表示不能有任何文本在文本的前面后后面,只能是行首和行尾。
完整的匹配邊界列表,在本文最后列出。
量詞匹配
量詞可以匹配一個表達式多次出現。例如下列表達式匹配字母A 出現0次或多次。
A*
量詞 * 表示0次或多次。+ 表示1次或多次。? 表示0次或1次。還有些其他量詞,參見本文后面的列表。
量詞匹配分為 饑餓模式,貪婪模式,獨占模式。饑餓模式 匹配盡可能少的文本。貪婪模式匹配盡可能多的文本。獨占模式匹配盡可能多的文本,甚至導致剩余表達式匹配失敗。
以下演示饑餓模式,貪婪模式,獨占模式區別。假設以下文本:
John went forawalk, andJohn fell down, andJohn hurt his knee.
饑餓模式下 表達式:
John.*?
這個表達式匹配John 后跟0個或多個字符。 . 表示任意字符。* 表示0或多次。? 跟在 * 后面,表示 * 采用饑餓模式。
饑餓模式下,量詞只會匹配盡可能少的字符,即0個字符。上例中的表達式將會匹配單詞John,在輸入文本中出現3次。
如果改為貪婪模式,表達式如下:
John.*
貪婪模式下,量詞會匹配盡可能多的字符。現在表達式會匹配第一個出現的John,以及在貪婪模式下 匹配剩余的所有字符。這樣,只有一個匹配項。
最后,我們改為獨占模式:
John.*+hurt
*后跟+ 表示獨占模式量詞。
這個表達式在輸入文本中沒有匹配項,盡管文本中包括 John 和 hurt. 為什么會這樣? 因為 .*+ 是獨占模式。與貪婪模式下,盡可能多的匹配文本,以使整個表達式匹配不同。獨占模式會盡可能的多的匹配,但不考慮表達式剩余部分是否能匹配上。
.*+ 將會匹配第一個John之后的所有字符,這會導致表達式中剩余的 hurt 沒有匹配項。如果改為貪婪模式,會有一個匹配項。表達式如下:
John. *hurt
邏輯操作符
正則表達式支持少量的邏輯運算(與,或,非)。
與操作是默認的,表達式 John ,意味著J 與 o與h與n。
或操作需要顯示指定,用 | 表示。例如表達式 John|hurt 意味著John 或 hurt 。
字符
字符分類
內置字符分類
邊界匹配
量詞
我有一個微信公眾號,經常會分享一些Java技術相關的干貨。如果你喜歡我的分享,可以用微信搜索“Java團長”或者“javatuanzhang”關注。返回搜狐,查看更多
責任編輯:
總結
以上是生活随笔為你收集整理的java正则表达式 and_Java正则表达式详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java double 移位_【原创】J
- 下一篇: java正则表达式http_Java 正