iOS正則表達式探索

參考:正則表達式、正則表達式30分鐘入門教程、正則表達式的使用方法

一、概述

正則表達式(Regular Expression)是一種文本模式,包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為“元字符”)。

正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串。

正則表達式是繁瑣的,但它是強大的,學會之后的應用會讓你除了提高效率外,會給你帶來絕對的成就感。

二、簡介

除非您以前使用過正則表達式,否則您可能不熟悉一些術語。但是,毫無疑問,您已經使用過不涉及腳本的某些正則表達式概念。
例如,您很可能使用?*通配符來查找硬盤上的文件。?通配符匹配文件名中的0個或單個字符,而 *通配符匹配零個或多個字符。像 data?.dat這樣的模式將查找下列文件:

data1.dat
data2.dat
datax.dat
dataN.dat


使用*字符代替 ? 字符擴大了找到的文件的數量。data*.dat 匹配下列所有文件:

data.dat
data1.dat
data2.dat
data12.dat
datax.dat
dataXYZ.dat
ps:在OC中的結果,
`data?.dat `匹配
dat.dat
data.dat
datfdat
datagdat

`data*.dat `匹配
dat.dat
data.dat
dataa.dat
dataaa.dat
datfdat
datagdat
datahdat
我主要想說明的是.匹配任意字符
*匹配的是數量上0個或者多個(也就是說,可以沒有,可以有一個,也可以有多個)
?匹配的是數量上0個或者是1個(也就是可以也可以沒有)

盡管這種搜索方法很有用,但它還是有限的。通過理解 * 通配符的工作原理,引入了正則表達式所依賴的概念,但正則表達式功能更強大,而且更加靈活。
正則表達式的使用,可以通過簡單的辦法來實現強大的功能。下面先給出一個簡單的示例:

^[0-9]+abs$

  • ^ 為匹配輸入字符串的開始位置。
  • [0-9]+匹配多個數字,[0-9] 匹配單個數字,+匹配一個或者多個。
  • abc$匹配字母 abc 并以 abc 結尾,$ 為匹配輸入字符串的結束位置。

示例:
匹配以數字開頭,并以abc結尾的字符串。:

var str = "123abc";
var patt1 = /^[0-9]+abc$/;
document.write(str.match(patt1));

以下標記的文本是獲得的匹配的表達式:

123abc

ps:這只是在文件搜索系統中的正則看,在iOS中則略有不同,所以不要在OC中測試上述正則

為什么要使用正則表達式?

典型的搜索和替換操作要求您提供與預期的搜索結果匹配的確切文本。雖然這種技術對于靜態文本執行簡單的搜索和替換任務已經足夠了,但它缺乏靈活性,若采用這種方法搜索動態文本,即使不是不可能,至少也會變得很困難。

通過正則表達式,可以:

  • 測試字符串內的模式:
    例如,可以測試輸入字符串,以查看字符串是否出現電話號碼模式或信用卡號碼模式。這稱為數據驗證。

  • 替換文本。
    可以使用正則表達式來識別文檔中的特定文本,完全刪除該文本或者用其他文本替換它。

  • 基于模式匹配從字符串中提取子字符串。
    可以查找文檔內或者輸入域內特定的文本。

例如,您可能需要搜索整個網站,刪除過時的材料,以及替換某些HTML格式標記。在這種情況下,可以使用正則表達式來確定在每個文件中是否出現該材料或該HTML格式標記。此過程將受影響的文件列表縮小到包含需要刪除或更改的材料的那些文件。最后,可以通過正則表達式來搜索和替換標記。

三、正則表達式的語法

下面描述了正則表達式用于匹配字符串中的模式的字符表達式,制定模式匹配多少次的模式運算符和其他匹配限制,最后一個表指定可以包含在正則表達式中的標志通過多行指定搜索行為的模式(也可以使用選項標志來指定這些標志)

表1描述了用于匹配字符串中的字符的字符序列

表格1正則表達式元字符
字符表達 描述
\a 匹配BELL, \u0007
\A 在輸入開始時匹配。不同于^在\A輸入中的一個新行之后將不匹配。
\b, outside of a [Set] 如果當前位置是字邊界匹配。邊界發生word(\w)和非word(\W)字符之間的轉換處,組合標記被忽略。為了更好的字邊界,請參閱。NSRegularExpressionUseUnicodeWordBoundaries
\b, within a [Set] 匹配退格,\u0008。
\B 如果當前位置不是字邊界匹配。
\cX 匹配一個control-X字符
\d 匹配任何字符與Unicode通用類別的Nd(數字,十進制數字)
\D 匹配任何不是十進制數字的字符。
\e 匹配ESCAPE,\u001B。
\E 終止\Q ... \E引用的序列。
\f 匹配一個form feed,\u000C。
\G 如果當前位置在上一個匹配結束時匹配。
\n 匹配LINE FEED,\u000A。
\N{UNICODE字符名稱} 匹配named character。
\p{UNICODE PROPERTY NAME} 使用指定的Unicode屬性匹配任何字符。
\P{UNICODE PROPERTY NAME} 匹配任何不具有指定Unicode屬性的字符。
\Q 行情所有后續字符,直到\E。
\r 匹配運送返回,\ u000D。
\s 匹配一個空白字符??崭癖欢x為[\ t \ n \ f \ r \ p {Z}]。
\S 匹配非空白字符。
\t 匹配水平制表符,\u0009。
\uhh 匹配字符與十六進制值hh
\Uhhhhhhhhh 匹配字符與十六進制值hhhhhhhhhh。必須提供8位十六進位數字,即使是最大的Unicode代碼點\U0010ffff
\w 匹配一個字符 字符是[\ p {L1} \ p {Lu} \ p {Lt} \ p {Lo} \ p {Nd}]。
\W 匹配非字詞。
\x{hhhh} 匹配字符與十六進制值hhhh。可提供1到6個十六進制數字。
\x 匹配字符與兩位十六進制值hh
\X 匹配一個化身集群
\Z 如果當前位置在輸入結束處,而在最后一行終止符之前,則匹配,如果存在。
\z 如果當前位置在輸入結束時匹配。
\n 返回參考。匹配任何第n個捕獲組匹配。n必須是模式中的數字≥ 1和≤總數量的捕獲組。
\0ooo 匹配八進制字符 ooo是從一到三個八進制數字。0377是最大允許的八進制角色。領先的零是必需的; 它將八進制常數與反向引用區分開來。
[pattern] 匹配模式中的任何一個字符。
. 匹配任何角色 見并且在字符表達式表4。NSRegularExpressionDotMatchesLineSeparators
^ 在一行開始匹配 見并且在字符表達式表4NSRegularExpressionAnchorsMatchLines\m
$ 在一行結束時匹配。見并且在字符表達式表4NSRegularExpressionAnchorsMatchLines
引用以下字符。必須引用被視為文字的字符是* ? + [ ( ) { } ^ $ \ . /

正則表達式運算符

表2正則表達式運算符
操作 描述
交替 (甲 乙)要么匹配甲或乙。
* 0或者是更多次數的匹配
+ 1或更多次 匹配盡可能多的次數。
? 匹配零次或一次
{n} 完全匹配n次
{n,} 至少匹配n次 匹配盡可能多的次數。
{n ,m} n和m之間的匹配。匹配盡可能多的次數,但不能超過m。
*? 匹配0或更多次 匹配盡可能少的次數。
+? 比賽1次以上 匹配盡可能少的次數。
?? 匹配零次或一次。更偏好零。
{n}? 完全匹配n次
{n,}? 匹配至少n次,但不超過整體模式匹配所需。
{n,m}? n和m之間的匹配。匹配次數盡可能少,但不小于n。
*+ 匹配0次以上。在第一次遇到時,盡可能多地匹配,即使整體匹配失敗(Possessive Match)也不要重試。
++ 匹配一次以上 possessive match
?+ 匹配零次或一次。possessive match
{n}+ 完全匹配n次
{n,}+ 至少匹配n次possessive match
{n,m}+ n和m之間的匹配次數,possessive match
(...) 捕獲括號。匹配圓括號子表達式的輸入范圍在匹配后可用
(?:...) 非捕獲括號。對包含的模式進行分組,但不提供匹配文本的捕獲。比捕捉括號更有效率。
(?>...) 原子匹配括號。括號子表達式的第一個匹配是唯一一個嘗試; 如果它不會導致整體模式匹配,請在“ (?>” 之前的位置備份搜索匹配
(?# ... ) 自由格式的評論(?# comment )。
(?= ... ) 先行斷言 如果括號內的圖案在當前輸入位置匹配,但不會提前輸入位置,則為真。
(?! ... ) 負面的預言斷言。如果括號中的圖案在當前輸入位置不匹配,則為真。不提高輸入位置。
(?<= ... ) 瞻性斷言 如果括號中的模式與當前輸入位置之前的文本匹配,則匹配的最后一個字符就是當前位置之前的輸入字符。不改變輸入位置。由look-behind模式匹配的可能字符串的長度不能是無限制的(否*或+運算符。
(?<! ... ) 負面看法斷言。如果括號中的模式與當前輸入位置之前的文本不匹配,則匹配的最后一個字符就是當前位置之前的輸入字符。不改變輸入位置。由look-behind模式匹配的可能字符串的長度不能是無限制的(否*或+運算符。)
(?ismwx-ismwx: ... ) 標志設置。使用指定的啟用或禁用的標志來評估括號中的表達式。標志在標志選項中定義。
(?ismwx-ismwx) 標志設置。更改標志設置。更改適用于設置后的模式部分。例如,(?i)更改為不區分大小寫的匹配。標志在標志選項中定義。

模板匹配格式

本類提供了使用模板匹配的技術既可變和不可變的字符串查找和替換的方法。表3描述了語法。

表3模板匹配格式
字符 描述
$n 捕獲組n的文本將被替換為$ n。n必須>= 0和不大于捕獲組的數量。一個$沒有后面的數字沒有什么特別的意義,并且會以替代文本的形式出現在自己身上$。
將以下字符視為文字,抑制任何特殊含義。替換文本中的反斜杠轉義只適用于'$'和'',但可以用于任何其他字符而不會產生不良影響。

替換字符串被視為模板,$0被匹配范圍$1的內容,第一個捕獲組的內容替換,等等。除了表示捕獲組數量所需的最大值之外的其他數字將被視為普通字符,$不會跟隨數字。反斜杠將難逃都$和\

標記選項

以下標志控制正則表達式匹配的各個方面。
可以使用(?ismx-ismx)模式選項在模式中指定這些標志值。當使用選項標志初始化時,可以為整個模式指定等效的行為。
NSRegularExpressionNSRegularExpressionOptions

表4 標記選項
flag(pattern) 描述
i 如果設置,匹配將以不區分大小寫的方式進行。
X 如果設置,允許在模式中使用空格和#comments
s 如果設置,.模式中的“ ”將匹配輸入文本中的行終止符。默認情況下,它不會。請注意,carriage-return / line-feed pair文本中的內容表現為單行終止符,并將匹配.正則表達式模式中的單個“ ”
m 以模式控制“ ^”和“ $” 的行為。默認情況下,這些僅分別匹配輸入文本的開始和結束。如果設置了這個標志,“ ^”和“ $”也將在輸入文本的每一行的開頭和結尾相匹配。
w 控制模式中的行為\b。如果設置,則根據Unicode UAX 29“文本邊界”中發現的詞的定義找到字邊界。默認情況下,通過將字符簡單地分類為“單詞”或“非單詞”來識別字邊界,其近似于傳統的正則表達行為。使用兩個選項獲得的結果在空格和其他非字符字符的運行中可能會有很大差異。

性能

NSRegularExpression
實現了非確定性有限自動機匹配引擎。因此,當嘗試執行匹配時,包含多個*或+運算符的復雜正則表達式模式可能會導致較差的性能 -特別是無法匹配給定的輸入。有關更多信息,請參閱“ICU用戶指南”“性能提示”部分。

四、OC中的Regular表達式NSRegularExpression

NSRegularExpression被設計為不可變的和線程安全的,因此可以一次使用單個實例來匹配多個線程上的操作。但是,在匹配操作的過程中,無論是從另一個線程還是在迭代中使用的塊內,不應該在其上操作它的字符串。

1、創建正在表達式
2、獲取正則表達式和選項
3、使用正則表達式搜索字符串

- firstMatchInString:options:range:
返回字符串指定范圍內正則表達式的第一個匹配項。

4、使用正則表達式替換字符串
5、在字符串中轉義
  • + escapedTemplateForString:
    通過根據需要添加反斜杠轉義來返回模板字符串,以保護符合模式元字符的任何字符

  • + escapedPatternForString:
    通過根據需要添加反斜杠轉義來返回字符串,以保護符合模式元字符的任何字符。

6、自定義替換功能
7、常數

五、optionals

1、NSMatching 選項

匹配選項常量指定表達式匹配方法的報告,完成和匹配規則。所有使用正則表達式搜索或替換值的方法都使用這些常量。

2、NSRegular表達式選項

五、正則表達式的使用

1、謂詞(NSPredicate)創建正則表達式

使用它來判斷用戶輸入的字符串是否為合法的:

// 編寫正則表達式:只能是數字或英文,或兩者都存在
NSString *regex = @"^[a-z0-9A-Z]*$";
// 創建謂詞對象并設定條件的表達式
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
// 判斷的字符串
NSString *str = @"Hello100";
// 對字符串進行判斷
if ([predicate evaluateWithObject:str]) {
    NSLog(@"Match");
}
2、NSString實例方法

使用rangeOfString:options:方法可以做到,具體看例子:

NSString *phoneNo = @"13143503442";
NSRange range = [phoneNo rangeOfString:@"^1[3]\\d{9}$" options:NSRegularExpressionSearch];
if (range.location != NSNotFound) {
    NSLog(@"%@", [phoneNo substringWithRange:range]);
}

rangeOfString:options:會返回一個NSRange,用來接收匹配的范圍,當匹配不到結果時,將會返回一個NSIntegerMax最大值,也就是NSNotFound,因此我們可以用它來判斷用戶輸入的內容是否符合規則。

3、NSRegularExpression類創建正則表達式

我們可以使用正則來過濾并獲取我們想要的特定部分,實現方法也很簡單,可以用到NSRegularExpression這個類實現:

NSString *url = @"1229436624@qq.com";
NSError *error;
// 創建NSRegularExpression對象并指定正則表達式
NSRegularExpression *regex = [NSRegularExpression
                              regularExpressionWithPattern:@"[^@]*\\."
                              options:0
                              error:&error];
if (!error) { // 如果沒有錯誤
    // 獲取特特定字符串的范圍
    NSTextCheckingResult *match = [regex firstMatchInString:url
                                                    options:0
                                                      range:NSMakeRange(0, [url length])];
    if (match) {
        // 截獲特定的字符串
        NSString *result = [url substringWithRange:match.range];
        NSLog(@"%@",result);
    }
} else { // 如果有錯誤,則把錯誤打印出來
    NSLog(@"error - %@", error);
}

這個例子是從字符串里檢索出以“@”開頭“.”結尾的區間字符串,最后檢索出來的字符串結尾包括“.”,因此此例子最終輸出結果為“qq.”

4、NSRegularExpression類之抓取多個結果

當一個字符串有多個符合特定規則的字符,我們可以分別獲取到符合特定規則的字符:

NSString *regex = @"\\-\\d*\\.";
NSString *str = @"-34023242.-34203020.";
NSError *error;
NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:regex
                                                                         options:NSRegularExpressionCaseInsensitive
                                                                           error:&error];
// 對str字符串進行匹配
NSArray *matches = [regular matchesInString:str
                                    options:0
                                      range:NSMakeRange(0, str.length)];
// 遍歷匹配后的每一條記錄
for (NSTextCheckingResult *match in matches) {
    NSRange range = [match range];
    NSString *mStr = [str substringWithRange:range];
    NSLog(@"%@", mStr);
}

從指定字符串中獲取以“-”開頭以“.”結尾的字符,因為可能有多個符合特定規則的字符串,因此我們需要把它們遍歷出來,具體輸出結果如下

017-05-02 16:38:52.309 Juny_regularDemo[1669:190937] -34023242.
2017-05-02 16:38:52.310 Juny_regularDemo[1669:190937] -34203020.

總結:一般來說,判斷用戶輸入的是否合法,只需要方法一就可以了。如果是需要捕獲用戶輸入的特定內容,可以用方法二或者方法三、四,如果可能有多個捕獲結果,那么可以使用方法四,否則使用方法二。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,247評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,520評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,362評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,805評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,541評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,896評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,887評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,062評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,608評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,356評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,555評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,077評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,769評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,175評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,489評論 1 295
  • 沈念sama閱讀 52,289評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,516評論 2 379

推薦閱讀更多精彩內容

  • iOS中使用正則表達式就不得不提NSRegularExpression,所以我們需要先搞清楚什么是NSRegula...
    sunmumu1222閱讀 2,365評論 0 4
  • 推薦幾個正則表達式編輯器 Debuggex :https://www.debuggex.com/ PyRegex:...
    木易林1閱讀 11,530評論 9 151
  • 幾個正則表達式編輯器 Debuggex :https://www.debuggex.com/ PyRegex:ht...
    沒技術的BUG開發攻城獅閱讀 4,613評論 0 23
  • 初衷:看了很多視頻、文章,最后卻通通忘記了,別人的知識依舊是別人的,自己卻什么都沒獲得。此系列文章旨在加深自己的印...
    DCbryant閱讀 4,042評論 0 20
  • 正則表達式又稱為正規表示法、規則表達式、常規表示法,英語為Regular Expression,常簡寫為regex...
    pro648閱讀 5,450評論 1 11