正規表示式之(exp),(?:exp),(?=exp) 理解

風靈使發表於2018-08-02

先澄清下如下倆個概念:

1、分組(或捕獲組)

分組的定義

正規表示式通過使用括號將表示式分為不同的分組,識別的方法是通過從左至右搜尋左半括號,遇到第一個左半括號時,則該左半括號與對應的右半括號所包含的內容即為第一分組,以此類推 。例如,在表示式((A)(B(C))),有四個這樣的組:((A)(B(C)))、(A)、(B(C))、(C)

分組存在意義

向後引用:在第i個分組中被匹配的字串,可以在在正規表示式中通過\i方式再次引用,例如\b(\w+)\b\s+\1\b可以用來匹配重複的單詞,像go go, 或者kitty kitty

分組取值:當通過正規表示式匹配到字串時,可以使用matcher.group(i)等方式取到第i個分組所匹配到的子字串。

2、位置類後設資料

即像^$\b\B這樣的元字元,是用來表示一個位置。作為一個判斷條件,匹配的字元需要滿足這樣的位置資訊,但最終匹配的字串中並不會包含這個樣的位置資訊。這也是與其他一些元字元所區別的地方,例如表示式中出現\d這樣元字元,則最終匹配的字串中必定需要有數字出現,而\b(\w+)\b表示式匹配的字串僅僅是一個完整的單詞,而不會出現空格等字元來表達位置資訊。

其實清楚上面倆個概念後,下面的也就不難理解了:

(exp) :目標字串需要匹配exp,並將該分組匹配的子文字儲存到自動命名的組裡;

(?<name>exp):目標字串需要匹配exp,並將該分組匹配的子文字儲存到名稱為name的組裡,也可以寫成(?'name'exp)

(?:exp) :目標字串需要匹配exp, 該括號所包括的內容不會被作為一個分組對待, 即不給此“分組”分配組號,也不會並將該”分組”匹配的子文字儲存;該表示式與(exp)在效果上其實應該是沒有區別的,區別只是是否算作一個分組及是否儲存匹配的子文字。

(?=exp) :定義目標字串結束位置要求,即緊隨目標字串後面出現的字串需要匹配上exp表示式,該字串不會被計入目標字串,表達中出現的括號也不會被視作一個分組;

(?<=exp):定義目標字串起始位置要求,即緊鄰目標字串前面出現的字串需要匹配上exp表示式,該字串不會被計入目標字串,表達中出現的括號也不會被視作一個分組;

(?!exp):定義目標字串結束位置要求,即緊隨目標字串後面出現的字串不能匹配上exp表示式,該字串不會被計入目標字串,表達中出現的括號也不會被視作一個分組;效果上與(?=exp) 表示的情況剛好相反;

(?<!exp):定義目標字串起始位置要求,即緊鄰目標字串前面出現的字串不能匹配上exp表示式,該字串不會被計入目標字串,表達中出現的括號也不會被視作一個分組;效果上與(?<=exp)表示的情況剛好相反;

相關文章