iOS深思篇 | 正則表達式

一. 背景

1.1 簡介

關於正則表達式,相信你們並不陌生,可能平時只是粘貼下相關代碼,並不瞭解裏面所寫匹配規則。這篇文章咱們將介紹iOS相關正則表達式基本語法和一些實例,但願看完此文你們能有所收穫;html

1.2 工具

在線匹配工具java

安裝包git

圖形化展現工具github

eg:正則表達式

regulex實例展現圖

objective-c

二. 認識正則表達式

2.1 概念

正則表達式(又稱規則表達式),英語爲Regular Expression,常簡寫爲regexregexpRE。它使用單個字符串來描述,匹配一系列符合某個句法規則的字符串。express

使用場景:bash

  • 用來批量提取或替換有規律的字符串;
  • 在高級文本編輯器中使用;
  • 在各種辦公軟件(office等)中使用;
  • 檢測用戶的輸入是否合法;
  • 在各類開發語言中使用;(C#,java,JS,PHP等)
  • 網絡爬蟲;
  • 批量文本處理等;

eg:網絡

Xcode使用場景編輯器

2.2 初識篇

正則表達式是由普通字符和特殊字符(也叫元字符或限定符)組成的文字模板,爲用來描述或匹配符合某個句法規則的字符串。在許多軟件中都獲得普遍的應用,固然針對不一樣的命令及環境,對正則表達式的支持程度也不盡相同,這裏參考正則表達式 - 應用領域。有一個通識問題說明一下:

"/"是JS中常常用來分隔一個正則的開始與結尾的字符,其餘語言中不用作此區分;

好比:

/* JS */
 /abc/           //精確匹配abc(有/符號)

/* 其餘語言 */
  abc            //精確匹配abc(無/符號)
複製代碼

不少人剛開始無從下手多是由於不清楚如何"斷句",這樣也就抓不住重點,感受像聽天書了。🤔咱們能夠這樣拆開來看,把正則表達式當作是普通字符和其餘字符的集合。普通字符包括全部大寫和小寫字母、全部數字、全部標點符號和一些其餘符號(PS:就是平時看得懂的符號🙄);其餘字符包括了常說的元字符、運算符、限定符、特殊字符等等;

下面是一個匹配以數字開頭,並以 abc 結尾的字符串;

^    [0-9]    +      abc     $


定位符  字符集  限定符  普通字符  限定符
複製代碼

各類字符的詳細解釋可參照正則表達式 - 語法。以後稍微瞭解一點語法,就能夠嘗試本身斷句了,爲了少走彎路,建議參照圖形化展現工具regulex對比理解。

2.3 語法篇

語法篇主要參照learn-regex的劃分;你們能夠參照做者的在線練習進行學習,下面👇僅附上主要元字符對照表。

2.3.1 元字符

正則表達式主要依賴於元字符. 元字符不表明他們自己的字面意思, 他們都有特殊的含義. 一些元字符寫在方括號中的時候有一些特殊的意思. 如下是一些元字符的介紹:

元字符 描述
. 句號匹配任意單個字符除了換行符.
[ ] 字符種類. 匹配方括號內的任意字符.
[^ ] 否認的字符種類. 匹配除了方括號裏的任意字符
* 匹配>=0個重複的在*號以前的字符.
+ 匹配>=1個重複的+號前的字符.
? 標記?以前的字符爲可選.
{n,m} 匹配num個大括號以前的字符 (n <= num <= m).
(xyz) 字符集, 匹配與 xyz 徹底相等的字符串.
| 或運算符,匹配符號前或後的字符.
\ 轉義字符,用於匹配一些保留的字符 [ ] ( ) { } . * + ? ^ $ \ |
^ 從開始行開始匹配.
$ 從末端開始匹配.
2.3.2 簡寫字符集

正則表達式提供一些經常使用的字符集簡寫. 以下:

簡寫 描述
. 除換行符外的全部字符
\w 匹配全部字母數字, 等同於 [a-zA-Z0-9_]
\W 匹配全部非字母數字, 即符號, 等同於: [^\w]
\d 匹配數字: [0-9]
\D 匹配非數字: [^\d]
\s 匹配全部空格字符, 等同於: [\t\n\f\r\p{Z}]
\S 匹配全部非空格字符: [^\s]
\f 匹配一個換頁符
\n 匹配一個換行符
\r 匹配一個回車符
\t 匹配一個製表符
\v 匹配一個垂直製表符
\p 匹配 CR/LF (等同於 \r\n),用來匹配 DOS 行終止符
2.3.3 零寬度斷言(先後預查)

先行斷言和後發斷言都屬於非捕獲簇(不捕獲文本 ,也不針對組合計進行計數). 先行斷言用於判斷所匹配的格式是否在另外一個肯定的格式以前, 匹配結果不包含該肯定格式(僅做爲約束).

例如, 咱們想要得到全部跟在 $ 符號後的數字, 咱們可使用正後發斷言 (?<=\$)[0-9\.]*. 這個表達式匹配 $ 開頭, 以後跟着 0,1,2,3,4,5,6,7,8,9,. 這些字符能夠出現大於等於 0 次.

零寬度斷言以下:

符號 描述
?= 正先行斷言-存在
?! 負先行斷言-排除
?<= 正後發斷言-存在
?<! 負後發斷言-排除
2.3.4 標誌

標誌也叫模式修正符, 由於它能夠用來修改表達式的搜索結果. 這些標誌能夠任意的組合使用, 它也是整個正則表達式的一部分.

標誌 描述
i 忽略大小寫.
g 全局搜索.
m 多行的: 錨點元字符 ^ $ 工做範圍在每行的起始.
2.3.5 優先級

在這些運算符同時出現時,按照下面的優先級進行操做。

優先級 符號
最高 \
( )、(?: )、(?= )、[ ]
*、+、?、{n}、{n,}、{n,m}
^、$、中介字符
最低 |

2.4 進階篇

2.4.1 貪婪匹配與惰性匹配

正則表達式默認採用貪婪匹配模式,在該模式下意味着會匹配儘量長的子串。咱們可使用 ? 將貪婪匹配模式轉化爲惰性匹配模式。 貪婪模式

(.*nt) => People want to try something different.

惰性模式

(.*?nt) => People want to try something different.

常見的惰性限定符:

符號 說明
*? 重複任意次,但儘量少重複
+? 重複1次或更屢次,但儘量少重複
?? 重複0次或1次,但儘量少重複
{n,m}? 重複n到m次,但儘量少重複
{n,}? 重複n次以上,但儘量少重複

三. iOS中的應用

3.1 謂詞(NSPredicate)

NSString *regex = @"^[0-9]+$";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    NSString *str = @"1314";
    if ([predicate evaluateWithObject:str]) {
        NSLog(@"Condition Matched");
    }
複製代碼

3.2 NSString

NSString *searchText = @"targetString";
    NSRange range = [searchText rangeOfString:@"^[0-9]+$" options:NSRegularExpressionSearch];
    if (range.location != NSNotFound) {
        NSLog(@"target range :%@", [searchText substringWithRange:range]);
    }
複製代碼

3.3 NSRegularExpression

/*
typedef NS_OPTIONS(NSUInteger, NSRegularExpressionOptions) {
   NSRegularExpressionCaseInsensitive             = 1 << 0, //不區分字母大小寫的模式
   NSRegularExpressionAllowCommentsAndWhitespace  = 1 << 1, //忽略掉正則表達式中的空格和#號以後的字符
   NSRegularExpressionIgnoreMetacharacters        = 1 << 2, //將正則表達式總體做爲字符串處理
   NSRegularExpressionDotMatchesLineSeparators    = 1 << 3, //容許.匹配任何字符,包括換行符
   NSRegularExpressionAnchorsMatchLines           = 1 << 4, //容許^和$符號匹配行的開頭和結尾
   NSRegularExpressionUseUnixLineSeparators       = 1 << 5, //設置\n爲惟一的行分隔符,不然全部的都有效。
   NSRegularExpressionUseUnicodeWordBoundaries    = 1 << 6 //使用Unicode TR#29標準做爲詞的邊界,不然全部傳統正則表達式的詞邊界都有效
};
*/
      NSString *searchText = @"what do you want to match string";
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[0-9]+$" options:NSRegularExpressionCaseInsensitive error:&error];

    //僅取出第一條匹配記錄
    NSTextCheckingResult *firstResult = [regex firstMatchInString:searchText options:0 range:NSMakeRange(0, [searchText length])];
    if (firstResult) {
        NSLog(@"firstResult:%@", [searchText substringWithRange:firstResult.range]);
    }

    //遍歷全部匹配記錄
    NSArray *matches = [regex matchesInString:searchText
                                        options:0
                                          range:NSMakeRange(0, searchText.length)];
    for (NSTextCheckingResult *match in matches) {
        NSRange range = [match range];
        NSString *mStr = [searchText substringWithRange:range];
        NSLog(@"AllResult:%@", mStr);
    }
複製代碼

學習:

blog

book

video

系列文章:

相關文章
相關標籤/搜索