1. 程式人生 > >java中正則表示式工具類:Pattern和Macher

java中正則表示式工具類:Pattern和Macher

原地址

java.util.regex是一個用正則表示式所訂製的模式來對字串進行匹配工作的類庫包。

1.簡介:

java.util.regex是一個用正則表示式所訂製的模式來對字串進行匹配工作的類庫包。
它包括兩個類:Pattern和Matcher 。

Pattern: 一個Pattern是一個正則表示式經編譯後的表現模式。

Matcher: 一個Matcher物件是一個狀態機器,它依據Pattern物件做為匹配模式對字串展開匹配檢查。

首先一個Pattern例項訂製了一個所用語法與PERL的類似的正則表示式經編譯後的模式,然後一個Matcher例項在這個給定的Pattern例項的模式控制下進行字串的匹配工作。

以下我們就分別來看看這兩個類:

2.Pattern類:

Pattern的方法如下:

static Pattern compile(String regex)
將給定的正則表示式編譯並賦予給Pattern類
static Pattern compile(String regex, int flags)
同上,但增加flag引數的指定,可選的flag引數包括:CASE INSENSITIVE,MULTILINE,DOTALL,UNICODE CASE, CANON EQ
int flags()
返回當前Pattern的匹配flag引數.
Matcher matcher(CharSequence input)
生成一個給定命名的Matcher物件
static boolean matches(String regex, CharSequence input)
編譯給定的正則表示式並且對輸入的字串以該正則表示式為模開展匹配,該方法適合於該正則表示式只會使用一次的情況,也就是隻進行一次匹配工作,因為這種情況下並不需要生 成一個Matcher例項。
String pattern()
返回該Patter物件所編譯的正則表示式。
String[] split(CharSequence input)
將目標字串按照Pattern裡所包含的正則表示式為模進行分割。
String[] split(CharSequence input, int limit)
作用同上,增加引數limit目的在於要指定分割的段數,如將limi設為2,那麼目標字串將根據正則表示式分為割為兩段。

一個正則表示式,也就是一串有特定意義的字元,必須首先要編譯成為一個Pattern類的例項,這個Pattern物件將會使用matcher()方法來生成一個Matcher例項,接著便可以使用該 Matcher例項以編譯的正則表示式為基礎對目標字串進行匹配工作,多個Matcher是可以共用一個Pattern物件的。

現在我們先來看一個簡單的例子,再通過分析它來了解怎樣生成一個Pattern物件並且編譯一個正則表示式,最後根據這個正則表示式將目標字串進行分割:

import java.util.regex.*; 
public class Replacement{ 
public static
void main(String[] args) throws Exception { // 生成一個Pattern,同時編譯一個正則表示式 Pattern p = Pattern.compile("[/]+"); //用Pattern的split()方法把字串按"/"分割 String[] result = p.split( "Kevin has seen《LEON》seveal times,because it is a good film." +"/ 凱文已經看過《這個殺手不太冷》幾次了,因為它是一部" +"好電影。/名詞:凱文。"); for (int i=0; i<result.length; i++) System.out.println(result[i]); } }

輸出結果為:
Kev

in has seen《LEON》seveal times,because it is a good film.
凱文已經看過《這個殺手不太冷》幾次了,因為它是一部好電影。
名詞:凱文。

很明顯,該程式將字串按”/”進行了分段。

我們以下再使用 split(CharSequence input, int limit)方法來指定分段的段數,程式改動為:
tring[] result = p.split(“Kevin has seen《LEON》seveal times,because it is a good film./ 凱文已經看過《這個殺手不太冷》幾次了,因為它是一部好電影。/名詞:凱文。”,2);
這裡面的引數”2”表明將目標語句分為兩段。
輸出結果則為:
Kevin has seen《LEON》seveal times,because it is a good film.
凱文已經看過《這個殺手不太冷》幾次了,因為它是一部好電影。/名詞:凱文。

3.Matcher類:

Matcher方法如下: Matcher appendReplacement(StringBuffer sb, String replacement)
將當前匹配子串替換為指定字串,並且將替換後的子串以及其之前到上次匹配子串之後的字串段新增到一個StringBuffer物件裡。
StringBuffer appendTail(StringBuffer sb)
將最後一次匹配工作後剩餘的字串新增到一個StringBuffer物件裡。
int end()
返回當前匹配的子串的最後一個字元在原目標字串中的索引位置 。
int end(int group)
返回與匹配模式裡指定的組相匹配的子串最後一個字元的位置。
boolean find()
嘗試在目標字串裡查詢下一個匹配子串。
boolean find(int start)
重設Matcher物件,並且嘗試在目標字串裡從指定的位置開始查詢下一個匹配的子串。
String group()
返回當前查詢而獲得的與組匹配的所有子串內容
String group(int group)
返回當前查詢而獲得的與指定的組匹配的子串內容
int groupCount()
返回當前查詢所獲得的匹配組的數量。
boolean lookingAt()
檢測目標字串是否以匹配的子串起始。
boolean matches()
嘗試對整個目標字元展開匹配檢測,也就是隻有整個目標字串完全匹配時才返回真值。
Pattern pattern()
返回該Matcher物件的現有匹配模式,也就是對應的Pattern 物件。
String replaceAll(String replacement)
將目標字串裡與既有模式相匹配的子串全部替換為指定的字串。
String replaceFirst(String replacement)
將目標字串裡第一個與既有模式相匹配的子串替換為指定的字串。
Matcher reset()
重設該Matcher物件。
Matcher reset(CharSequence input)
重設該Matcher物件並且指定一個新的目標字串。
int start()
返回當前查詢所獲子串的開始字元在原目標字串中的位置。
int start(int group)
返回當前查詢所獲得的和指定組匹配的子串的第一個字元在原目標字串中的位置。
(光看方法的解釋是不是很不好理解?不要急,待會結合例子就比較容易明白了)

一個Matcher例項是被用來對目標字串進行基於既有模式(也就是一個給定的Pattern所編譯的正則表示式)進行匹配查詢的,所有往Matcher的輸入都是通過CharSequence介面提供的,這樣做的目的在於可以支援對從多元化的資料來源所提供的資料進行匹配工作。
我們分別來看看各方法的使用:
★matches()/lookingAt ()/find():
一個Matcher物件是由一個Pattern物件呼叫其matcher()方法而生成的,一旦該Matcher物件生成,它就可以進行三種不同的匹配查詢操作:
matches()方法嘗試對整個目標字元展開匹配檢測,也就是隻有整個目標字串完全匹配時才返回真值。
lookingAt ()方法將檢測目標字串是否以匹配的子串起始。
find()方法嘗試在目標字串裡查詢下一個匹配子串。
以上三個方法都將返回一個布林值來表明成功與否。
★replaceAll ()/appendReplacement()/appendTail():
Matcher類同時提供了四個將匹配子串替換成指定字串的方法:
replaceAll()
replaceFirst()
appendReplacement()
appendTail()
replaceAll()與replaceFirst()的用法都比較簡單,請看上面方法的解釋。我們主要重點了解一下appendReplacement()和appendTail()方法。
appendReplacement(StringBuffer sb, String replacement) 將當前匹配子串替換為指定字串,並且將替換後的子串以及其之前到上次匹配子串之後的字串段新增到一個StringBuffer物件裡,而appendTail(StringBuffer sb) 方法則將最後一次匹配工作後剩餘的字串新增到一個StringBuffer物件裡。
例如,有字串fatcatfatcatfat,假設既有正則表示式模式為”cat”,第一次匹配後呼叫appendReplacement(sb,”dog”),那麼這時StringBuffer sb的內容為fatdog,也就是fatcat中的cat被替換為dog並且與匹配子串前的內容加到sb裡,而第二次匹配後呼叫appendReplacement(sb,”dog”),那麼sb的內容就變為fatdogfatdog,如果最後再呼叫一次appendTail(sb),那麼sb最終的內容將是fatdogfatdogfat。

還是有點模糊?那麼我們來看個簡單的程式:

//該例將把句子裡的"Kelvin"改為"Kevin" 
import java.util.regex.*; 
public class MatcherTest{ 
public static void main(String[] args) throws Exception { 
//生成Pattern物件並且編譯一個簡單的正則表示式"Kelvin" 
Pattern p = Pattern.compile("Kevin"); 
//用Pattern類的matcher()方法生成一個Matcher物件 
Matcher m = p.matcher("Kelvin Li and Kelvin Chan are both working in Kelvin Chen's KelvinSoftShop company"); 
StringBuffer sb = new StringBuffer(); 
int i=0; 
//使用find()方法查詢第一個匹配的物件 
boolean result = m.find(); 
//使用迴圈將句子裡所有的kelvin找出並替換再將內容加到sb裡 
while(result) { 
i++; 
m.appendReplacement(sb, "Kevin"); 
System.out.println("第"+i+"次匹配後sb的內容是:"+sb); 
//繼續查詢下一個匹配物件 
result = m.find(); 
} 
//最後呼叫appendTail()方法將最後一次匹配後的剩餘字串加到sb裡; 
m.appendTail(sb); 
System.out.println("呼叫m.appendTail(sb)後sb的最終內容是:"+ sb.toString()); 
} 
} 
最終輸出結果為: 
第1次匹配後sb的內容是:Kevin 
第2次匹配後sb的內容是:Kevin Li and Kevin 
第3次匹配後sb的內容是:Kevin Li and Kevin Chan are both working in Kevin 
第4次匹配後sb的內容是:Kevin Li and Kevin Chan are both working in Kevin Chen's Kevin 
呼叫m.appendTail(sb)後sb的最終內容是:Kevin Li and Kevin Chan are both working in Kevin Chen's KevinSoftShop company. 

看了上面這個例程是否對appendReplacement(),appendTail()兩個方法的使用更清楚呢,如果還是不太肯定最好自己動手寫幾行程式碼測試一下。
★group()/group(int group)/groupCount():
該系列方法與我們在上篇介紹的Jakarta-ORO中的MatchResult .group()方法類似(有關Jakarta-ORO請參考上篇的內容),都是要返回與組匹配的子串內容,下面程式碼將很好解釋其用法:

import java.util.regex.*; 
public class GroupTest{ 
public static void main(String[] args) 
throws Exception { 
Pattern p = Pattern.compile("(ca)(t)"); 
Matcher m = p.matcher("one cat,two cats in the yard"); 
StringBuffer sb = new StringBuffer(); 
boolean result = m.find(); 
System.out.println("該次查詢獲得匹配組的數量為:"+m.groupCount()); 
for (int i = 1; i <= m.groupCount(); i++) {
            System.out.println(m.group() + "\r\n" + m.group(1) + "\r\n" + m.group(2));
            System.out.println("*********");
        }
} 

輸出為: 
該次查詢獲得匹配組的數量為:2 
cat
ca
t
*********
cat
ca
t
*********

Matcher物件的其他方法因比較好理解且由於篇幅有限,請讀者自己程式設計驗證。

4.一個檢驗Email地址的小程式:

最後我們來看一個檢驗Email地址的例程,該程式是用來檢驗一個輸入的EMAIL地址裡所包含的字元是否合法,雖然這不是一個完整的EMAIL地址檢驗程式,它不能檢驗所有可能出現的情況,但在必要時您可以在其基礎上增加所需功能。

import java.util.regex.*; 
public class Email { 
public static void main(String[] args) throws Exception { 
String input = args[0]; 
//檢測輸入的EMAIL地址是否以 非法符號"."或"@"作為起始字元 
Pattern p = Pattern.compile("^.|^@"); 
Matcher m = p.matcher(input); 
if (m 
//檢測是否以"www."為起始 
p = Pattern.compile("^www."); 
m = p.matcher(input); 
if (m 
//檢測是否包含非法字元 
p = Pattern.compile("[^[email protected]_-~#]+"); 
m = p.matcher(input); 
StringBuffer sb = new StringBuffer(); 
boolean result = m.find(); 
boolean deletedIllegalChars = false; 
while(result) { 
//如果找到了非法字元那麼就設下標記 
deletedIllegalChars = true; 
//如果裡面包含非法字元如冒號雙引號等,那麼就把他們消去,加到SB裡面 
m.appendReplacement(sb, ""); 
result = m.find(); 
} 
m.appendTail(sb); 
input = sb.toString(); 
if (deletedIllegalChars) { 
System.out.println("輸入的EMAIL地址裡包含有冒號、逗號等非法字元,請修改"); 
System.out.println("您現在的輸入為: "+args[0]); 
System.out.println("修改後合法的地址應類似: "+input); 
} 
} 
} 
例如,我們在命令列輸入:java Email www.kevin

@163.net 
那麼輸出結果將會是:EMAIL地址不能以'www.'起始 
如果輸入的EMAIL為@kevin@163.net 
則輸出為:EMAIL地址不能以'.''@'作為起始字元 
當輸入為:cgjmail#$%@163.net 
那麼輸出就是: 
輸入的EMAIL地址裡包含有冒號、逗號等非法字元,請修改 
您現在的輸入為: cgjmail#$%@163.net 
修改後合法的地址應類似: cgjmail@163.net 

5.正則表示式規則:

字元
x 字元 x
\ 反斜線字元
\0n 八進位制值的字元0n (0 <= n <= 7)
\0nn 八進位制值的字元 0nn (0 <= n <= 7)
\0mnn 八進位制值的字元0mnn 0mnn (0 <= m <= 3, 0 <= n <= 7)
\xhh 十六進位制值的字元0xhh
\uhhhh 十六進位制值的字元0xhhhh
\t 製表符(‘\u0009’)
\n 換行符 (‘\u000A’)
\r 回車符 (‘\u000D’)
\f 換頁符 (‘\u000C’)
\a 響鈴符 (‘\u0007’)
\e 轉義符 (‘\u001B’)
\cx T對應於x的控制字元 x

字元類
[abc] a, b, or c (簡單類)
[^abc] 除了a、b或c之外的任意 字元(求反)
[a-zA-Z] a到z或A到Z ,包含(範圍)
[a-z-[bc]] a到z,除了b和c : [ad-z](減去)
[a-z-[m-p]] a到z,除了m到 p: [a-lq-z]
[a-z-[^def]] d, e, 或 f
備註:
方括號的正則表示式“t[aeio]n”只匹配“tan”、“Ten”、“tin”和“ton”,只能匹配單個字元。
圓括號,因為方括號只允許匹配單個字元;故匹配多個字元時使用圓括號“()”。比如使用“t(a|e|i|o|oo)n”正則表示式,就必須用圓括號。

預定義的字元類
. 任意字元(也許能與行終止符匹配,也許不能) 備註:句點符號代表任意一個字元。比如:表示式就是“t.n”,它匹配“tan”、“ten”、“tin”和“ton”,還匹配“t#n”、“tpn”甚至“t n”。
\d 數字: [0-9]
\D 非數字: [^0-9]
\s 空格符: [ \t\n\x0B\f\r]
\S 非空格符: [^\s]
\w 單詞字元: [a-zA-Z_0-9]
\W 非單詞字元: [^\w]

表達次數的符號
符號 次數
* 0次或者多次
+ 1次或者多次
? 0次或者1次
{n} 恰好n次
{n,m} 從n次到m次

相關推薦

java表示式工具PatternMacher

原地址 java.util.regex是一個用正則表示式所訂製的模式來對字串進行匹配工作的類庫包。 1.簡介: java.util.regex是一個用正則表示式所訂製的模式來對字串進行匹配工作的類庫包。 它包括兩個類:Pattern和Matcher

Java表示式相關PatternMatcher的使用

在Java中,java.util.regex包定義了正則表示式使用到的相關類,其中最主要的兩個類為:Pattern、Matcher:   Pattern 編譯正則表示式後建立一個匹配模式;   Matcher 使用Pattern例項提供的正則表示式對目標字串進行匹

java表示式運用例項(用String的matches方法演示)

java中正則表示式運用例項(參看java中正則表示式運用詳解): 測試程式碼  package test;   /**    * 在String的matches()方法,split()方法中使用正則表示式.    * @author fhd001    */   pu

表示式工具

1.  正則表示式匹配兩個指定字串中間的內容 public static List<String> getSubUtil(String soap,String rgex){ List<String> list = new ArrayList

java表示式的瞭解與實踐記錄

Pattern pattern = Pattern.compile("^\\S+/q/"); Matcher matcher = pattern.matcher(resultString); String qrcode=""; while(matcher.find()){ String path

Java 表示式

字元類: [abc] a、b 或 c [^abc] 任何字元,除了abc [a-zA-Z] a 到 z 或 A 到 Z ,兩頭的字母包括在內 [0-9] 0到9 的字元都包括 預定義字元類: . 任何字元 \d 數字:[0-9] 示例:判斷手機號的規則: String regex = “

1000行程式碼徒手寫表示式引擎【1】--JAVA表示式的使用

簡介: 本文是系列部落格的第一篇,主要講解和分析正則表示式規則以及JAVA中原生正則表示式引擎的使用。在後續的文章中會涉及基於NFA的正則表示式引擎內部的工作原理,並在此基礎上用1000行左右的JAVA程式碼,實現一個支援常用功能的正則表示式引擎。它支援貪婪匹配和懶惰匹配;支援零寬度字元(如“\b”, “\B

Java表示式匹配的語法規則

, package com.fsti.icop.util.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class RegExpValidatorUt

java表示式驗證日期

/** *正則表示式驗證日期格式     包括潤二月 **/ // public static void main(String[] args) { //  Pattern p = Pattern //      .compile("^((\\d{2}(([02468][

JAVA表示式的二次轉義

需求:格式化金額,替換伺服器返回的格式化字串中的”{0}”為金額 public class Test { public static void main(String[] args) { String unformattedMoney

Java表示式去除html標籤

    注:這是Java正則表示式去除html標籤方法。     private static final String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定義sc

Java表示式的分割案例

import java.util.Scanner; public class SplitDemo {/**正則表示式的分割案例:*  在鍵盤錄入一個年齡,判斷是不是按照你要求的年齡段。* @param args*/public static void main(String

JAVA表示式總結

下表顯示了正則表示式的語法: 表 1.1 正則表示式語法 元字元 說明 . 匹配任何單個字元。例如正則表示式“b.g”能匹配如下字串:“big”、“bug”、“b g”,但是不匹配“buug”。  $ 匹配行結束符。例如正則表示式“EJB$”能夠匹配字串“I like EJB”的末尾,但是不

Java表示式常用方法彙總

眾所周知,在程式開發中,難免會遇到需要匹配、查詢、替換、判斷字串的情況發生,而這些情況有時又比較複雜,如果用純編碼方式解決,往往會浪費程式設計師的時間及精力。因此,學習及使用正則表示式,便成了解決這一矛盾的主要手段。 大 家都知道,正則表示式是一種可以用於模式匹配和替換的規

java使用表示式從一長串字元獲取一段特徵字串

只能說String工具類太強大,導致一直以來,幾乎沒怎麼用到過正則表示式,現在突然要用到,參考正則表示式語法,摸索一上午才搞出來。記錄分享一下,以免忘記 從一長串字元中,截取出邀請碼,我想很多人都遇到過。 String s = "邀請您加入隨心購,自動搜尋淘寶天貓優惠券!先領券,再購

Java 知識點整理-8.表示式+Math+Random+System+BigInteger+BigDecimal+Date+SimpleDateFormat+Calendar

目錄 正則表示式 Math類 Random類 System類  BigInteger類 BigDecimal類 Date類(日期類) DateFormat類 SimpleDateFormat類 Calendar類 正則表示式 1、正則

java利用表示式提取字串的整數小數部分

最近開發遇到一個新的東西,就是前端傳過來一個字串,需要將裡面的數字提取出來,倒騰了一天,最後還是沒有倒騰出來,最後還是借鑑大佬的方法。記錄一下。 首先是前端傳來的字串“小明通過掃碼向你付款100000.566元”其中暱稱和金額不是固定的,其他是固定的。 於是便考慮使用“通過掃碼向你付

java 利用表示式去處字串的所有空格

轉載自xcmercy的部落格 目標 去除字串中所有的空白字元,包括空格、製表符、回車符等所有空白字元 思路 根據字串長度,利用迴圈遍歷字串此方法太笨拙。這裡利用正則表示式,匹配所有的空白字元,然後將匹配到的空白字元替換為 “” 空串即可。 程式碼 private St

JDK表示式庫詳解(一)

二、以下是自己對正則表示式的一些理解。    [size=medium]1. 正則表示式規則1.1 普通字元    字母、數字、漢字、下劃線、以及後邊章節中沒有特殊定義的標點符號,都是"普通字元"。表示式中的普通字元,在匹配一個字串的時候,匹配與之相同的一個字元。    舉例1:表示式 "c",在匹配字串 "

java中用表示式獲取一個指定的子字元在字串出現的指定次數的下標索引,並且進行字串分割

在開發中遇到這樣的一個報文: 00000123000003RQ0 ################ 000003 <tellerLvl0>0</><brc>3004</><fPIflag>0</><