正則表達式(Regular expression)

正則表達式:是處理字符串的一種表達方式,提供了一種從一組字符串中選擇特定字符串的機制
POSIX規范定義了 UNIX 操作系統支持的功能,POSIX 規范的正則表達式有兩種:

  • BRE (Basic Regular Expression) -- 基本型正則表達式
  • ERE (Extended Regular Expression) -- 擴展型正則表達式

這里需要注意一點:正則表達式通配符沒有任何關系,不是包含關系
1、通配符Shell提供的功能
2、正則表達式只是用來處理字符串


下面我們來看一個常見的正則表達式,手機號碼的判斷:

^1[3-9](\d{9})$
  • ^:錨點操作符,匹配字符串的開頭,這里緊跟著1表示以1開頭的字符串
  • []:列表操作符,只匹配中括號中的一個字符
  • -:范圍操作符,指定的范圍。3-9表示范圍在3和9之間
  • \d:代表0-9之間的數字
  • {}:間隔運算符,匹配前一個元素N次,這里表示匹配前一個元素9次
  • $錨點操作符,匹配字符串的結尾

字符匹配

  • 我們先來看一些常見的字符
字符 描述
[ABC] 匹配[...]中的所有字符,例:[qaz]匹配字符串"Tiktok Byte Dance"中所有的q a z字母
[^ABC] 匹配除了[...]中字符的所有字符,與 [ABC]相反
[A-Z] [A-Z]表示一個區間,匹配所有大寫字母,[a-z]表示所有小寫字母
. 匹配所有字符,除了\n \r和null(空字符),相當于[^\n\r]
\w 匹配字母、數字、下劃線。等價于[A-Za-z0-9]
  • 重復操作符
字符 描述
* 匹配前一個元素 0 次 或 多次
+ 匹配前一個元素 1 次 或 多次
? 匹配前一個元素 0 次 或 1次
  • 間隔操作符
字符 描述
{N} 匹配前一個元素 N 次,N是一個非負整數
{min,} 匹配前一個元素至少 min 次,min是一個非負整數
{min,max} 匹配前一個元素至少 min 次,至多 max 次;min和max均為非負整數注意逗號和兩個數之間不能有空格
  • 列表操作符
    [...] & [^...]
    一般操作符在列表操作符里會失去特殊意義,除了:
字符 描述
] 結束列表[]]
\ 轉義字符
[: 字符類別操作符開始
:] 字符類別操作符結束
- 范圍操作符,如0-9
  • 字符類別操作符
字符 匹配類型 描述
[:alnum:] [A-Za-z0-9] 匹配數字和字母
[:alpha:] [A-Za-z] 匹配字母
[:blank:] [\t] 匹配空格 和 Tab
[:cntrl:] [\x00-\x1F\x7F] 匹配控制符
[:digit:] [0-9] 匹配數字
[:graph:] \x21-\x7E 匹配可視字符
[:lower:] [a-z] 匹配小寫字母
[:print:] [\x20-\x7E] 匹配可視字符和空格
[:punct:] ][!"#$%&'()*+,./:;<=>?@^_`{}·~-] 匹配標點符號
[:space:] [\t\r\n\v\f] 空白字符
[:upper:] [A-Z] 匹配大寫字母字符
[:xdigit:] [A-Fa-f0-9] 匹配十六進制字符
  • 特殊類別操作符
字符 匹配類型 描述
\w [:alnum:] 匹配數字和字母
\d [:digit:] 匹配數字
\W [^[:alnum:]] 匹配除了數字和字母
\B [^[:digit:]] 匹配除了數字
\< ^ 匹配字符串的開頭
\> $ 匹配字符串的結尾
\b 匹配單詞邊界字符,to\b,但是不匹配tomorrow
  • 錨點操作符
字符 描述
^ 匹配字符串的開頭,需在開頭
$ 匹配字符串的結尾 或 換行符的前一個位置,需在結尾

?? 注意:如果^在列表操作符中使用,并且在首位,代表取反

操作符的優先級
優先級(由高到低) 操作符
歸類相關的括號符號 [::]
轉義字符 \<特殊字符>
括號表達 []
分組 ()
單字符重復 * + ? {m,n}
串聯 .
錨點 ^ $
備選 豎線(Markdown語法沖突,無法描述)

貪婪模式、勉強模式、侵占模式

貪婪匹配 勉強匹配 侵占匹配 描述
X? X?? X?+ 匹配X零次或一次
X* X*? X*+ 匹配X零次或多次
X+ X+? X++ 匹配X一次或多次
X{n} X{n}? X{n}+ 匹配Xn次
X{n,} X{n,}? X{n,}+ 匹配X至少n次
X{n,m} X{n,m}? X{n,m}+ 匹配X至少n次,但不超過m次
貪婪模式

例子:GoogleMaps

  • 模式:.*aps(貪婪模式) 由兩部分組成
    1、p1(.*) :匹配方式為貪婪型
    2、p2(aps)
    匹配開始:
  • 第一輪:
    首先,p1會匹配字符串中的所有字符GoogleMaps,匹配成功;但是p2沒有匹配字符,本輪匹配失敗。
  • 第二輪:
    減少p1的匹配量,留出最后一個字符,那么此時存在兩個字符串:s1代表GoogleMap / s2代表s。此時s1匹配p1,但是s2不匹配p2,本輪匹配失敗。
  • 第三輪:
    繼續減少p1的匹配量,留出兩個字符,結果同第二輪一樣。
  • 第四輪:
    再次減少p1的匹配量,字符串被分割成GoogleMaps兩個部分,此時p1和p2都能匹配。返回匹配成功。
勉強模式

例子:GoogleMaps

  • 模式:.*?aps(勉強模式) 最小匹配方式,同樣的分為兩部分
    1、p1(.*?) :匹配方式為勉強模式
    2、p2(aps)
    匹配開始:
  • 第一輪:p1由于是0次和任意次,首次匹配0次;則直接用字符串去匹配p2,但是p2無法匹配字符,本輪匹配失敗。
  • 第二輪:
    增加p1的匹配量,匹配G;此時存在兩個字符串,s1代表G / s2代表oogleMaps,s1匹配p1,但是s2不匹配p2,本輪匹配失敗。
    繼續上述匹配,直到滿足p2
侵占模式

例子:`GoogleMaps

  • 模式:.*+aps(侵占模式) ,同樣的分為兩部分
    1、p1(.*+) :匹配方式為勉強模式
    2、p2(aps)
    匹配開始時讀入所有字符串,和p1匹配成功;但沒有剩余字符串去和p2匹配,匹配失敗。

簡單講,貪婪模式和侵占模式相比,
1、貪婪模式會在只有部分匹配成功的條件下,依次從多到少,減少匹配成功部分的匹配量,將字符留給其他部分去匹配
2、而侵占模式則是占有所有能匹配成功的部分,絕不留給其他部分使用

iOS中正則表達式的應用

NSString *phoneNum = @"1384587921";
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^1[3-9]([:digit:]{9})$" options:NSRegularExpressionCaseInsensitive error:&error];
    NSTextCheckingResult *result = [regex firstMatchInString:phoneNum options:0 range:NSMakeRange(0, [phoneNum length])];
    
    if (result) {
        NSLog(@"匹配成功");
    } else {
        NSLog(@"匹配失敗");
    }

?????? 注意:正則表達式在不同的開發環境中是有所區別的,這一點需要在實際開發中靈活應用,比如:

image.png

在iOS的環境下,\d是不識別的。
這是因為OC 和 Swift 都要求 轉義文字字符串中的特殊字符(即:在它們前面加上反斜杠\)。反斜杠本身就是這樣的特殊字符之一,由于用于創建正則表達式的模式也是字符串,因此會增加復雜性,因為在使用Stingand時需要轉義反斜杠字符NSRegularWxpression。

這也就意味著標準正則表達式\d,將以\\d的形式出現在Swift 或 OC 代碼中。這一點大家要注意!

^1[3-9](\\d{9})$

參考文檔:正則表達式 - 語法

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容