java正規表示式的一些知識點

2021-05-27 13:29:23 字數 4362 閱讀 8758

由於正規表示式太過博大精深,這裡只記錄一些我所理解的常用的一些正則的知識點。

1.matcher的matches()方法、find()方法和group()方法

public static void main(string args) ");

matcher m = p.matcher(str);

system.out.println(m.matches());

while(m.find())

m.reset();

system.out.println("--------------");

while(m.find())

}

output:

false

deeeff

kkk--------------

abcdee

effkkk

從輸出可以看出matcher的matches()方法是將整個字串與正則匹配,如果不匹配就會輸出false,是從字串的左邊往右邊進行比較的。呼叫這個方法的時候比較完abc後,發現後面還有d,正則不能匹配,所以返回了false.

後面呼叫m.find(),嘗試查詢與該模式匹配的輸入序列的下乙個子串行。這個方法是使用子串行比較,matches()方法後匹配器已經匹配到d字母,那麼這個方法就從d字母開始匹配,才會輸出後面的3行內容。

m.group()就是返回匹配的子串行的內容,如果沒有匹配會拋異常,所以有必要先find()來確定有匹配的內容

m.reset()是重置匹配器。所以後面才會輸出匹配的4行內容。

注意:m.matches())會對m.find()產生影響。

小技巧:m.find()以後可以使用m.start()和m.end()獲得該串的其實和結束位置

2.pattern.compile(string regex, int flags)的使用

主要是後面的引數flags,

case_insensitive 大小寫不敏感

dotall             使.能匹配包括換行在內的任意字元(原本.是不能匹配換行的)

上**:

public static void main(string args) 

}

輸出:[abc][abc][abc][abc]

public static void main(string args) 

}

有的時候這兩個功能還是用的上的

3.正則中的貪婪型(greedy),勉強型(reluctant)和占有型(possessive)

貪婪型

前兩個比較簡單,只記錄下匹配的過程

public static void main(string args) ");

matcher m = p.matcher(str);

while(m.find())

}

輸出:[abcdef][ghijklmno]

匹配過程:由於是貪婪的,所以會盡可能多匹配,第一次匹配的時候會一直匹配到123前的f,到f後發現不符合了,本次匹配就結束了,第二次知道匹配了9個字元

勉強型

public static void main(string args) ?");

matcher m = p.matcher(str);

while(m.find())

}

輸出:[abc][def][ghi][jkl][mno]

匹配過程:從左到右,每次發現3個符合就匹配結束,這就是所謂的勉強型,不貪婪

占有型

某種意義上說,占有型和貪婪型是比較相似的,只是它有點「直腸子」,請看

public static void main(string args) f");

matcher m = p.matcher(str);

while(m.find())

}

輸出:[abcdef][ghijf]

這個是貪婪型,它的匹配過程是:

1.先找到盡可能多的匹配,先從a找到了f來匹配[a-z],1不符合要求後,開始匹配("[a-z]f"中的f,發現不匹配,就會將當前位置向前移乙個位置(因為它不是直腸子),然後發現f可以匹配,就輸出了結果。第二個結果也是類似的匹配過程。貪婪型發現後面匹配不上,會往回走的,這點很重要。

public static void main(string args) +");

matcher m = p.matcher(str);

while(m.find())

}

輸出:[abcdef][ghijfklm]

匹配過程:這個簡單的占有型匹配跟貪婪匹配沒有本質的區別,因為沒有能體現出他們區別的因素,請看

public static void main(string args) +f");

matcher m = p.matcher(str);

while(m.find())

}

輸出:無

匹配過程:先找到盡可能多的匹配,先從a找到了f來匹配[a-z],發現f後的1不符合,所以就開始匹配正則中的f,此時發現1與f不匹配。這時直接就會返回false,而不是像貪婪型那樣將當前位置回退乙個位置再進行匹配。因為占有型占有後就不會吐出來。這就是占有型和貪婪型的區別。需要在某些條件(一般是占有後面還需匹配)才能體現出與貪婪型的區別。

4.非捕獲匹配的使用(?=

x)(?!

x)(?<=

x)(?x)

非捕獲匹配的意思是匹配但是不捕獲,我覺得非捕獲匹配更像是定位匹配

(?=x)定位:該位置的右邊必須匹配x

public static void main(string args) ");

matcher m = p.matcher(str);

while(m.find())

}

輸出結果:[f12][fkl]

匹配過程:先定位(?=f)的作用是,先要找到這樣的位置,這個位置右邊第乙個字元要匹配f,也是就將位置定位在每個f前面,然後再進行後面的匹配。

那麼,如果將"(?=f)\\w"換成"\\w(?=f)"呢?

public static void main(string args) (?=f)");

matcher m = p.matcher(str);

while(m.find())

}

輸出:[cde][hij]

匹配過程:先找這樣的乙個位置,位置的右邊是f,然後往前匹配,也就是cde、hij的右邊都是f

注意:將(?=f)放在\\w左邊和放在右邊的區別,乙個是先找到位置,然後往後匹配,另乙個是找到位置,然後往前匹配。

(?!x)定位:與(?=x)正好相反

public static void main(string args) ");

matcher m = p.matcher(str);

while(m.find())

}

結果:[abc][def][123][ghi][jfk]

匹配過程:先找到這樣的位置,這個位置右側不能是f,然後匹配3個字元,這就是為什麼結果裡面沒有「fde」的原因

(?!f)放在\\w後面呢?找到這樣的3個字元,右邊不能緊挨著f。

(?<=x)和(?

輸出:[f12][klm]

匹配過程:先找到這樣的位置,左邊需要是f,也就是每個f後面,取3個字元應該是「[def][f12][klm]」但是後面的字元不能是f,所有def不滿足後面的條件。

5.向前引用的使用(自己備忘)

system.out.println("123412".matches("(\\w)\\w(\\1)"));                   //true

system.out.println("123456".matches("(\\w)\\w(\\1)"));                   //false

\\1代表的是前面匹配的內容12而不是\\w

title = title.replaceall("當前餘額.+?元","$0【您如果希望獲取餘額提醒,請定製餘額提醒服務】");

正規表示式知識點

re.match與re.search的區別 re.match只匹配字串的開始,如果字串開始不符合正規表示式,則匹配失敗,函式返回none 而re.search匹配整個字串,直到找到乙個匹配。flags 標誌位,用於控制正規表示式的匹配方式,如 是否區分大小寫,多行匹配等等 import re s 1...

正規表示式知識點

正則的知識點 1.建立例項 var reg new regexp pattern,flag d g 2.flag 識別符號 1.i 忽略大小寫匹配 2.m 多行匹配 3.g 全域性匹配 應用與所有,而不是找到第乙個就停止 3.第一段知識點 1.xyz xyz中任意乙個字元 等價於 x z 2.xyz...

正規表示式的一些知識

開發工具與關鍵技術 正規表示式正規表示式的知識點歸納 1.常用字元 1 意思是將下乙個字元標記為乙個特殊字元 或乙個原義字元 或乙個向後引用 或乙個八進位制轉義符。例如 n 匹配字元 n n 匹配乙個換行符。序列 匹配 而 則匹配 2 意思是匹配輸入字串的開始位置。如果設定了regexp物件的mul...