Implementing Regex in iOS

既然你有了這些基礎,就在APP中應用正則表達式吧。

如果你還沒有這樣做,下載 starter project 開始本教程吧。下載下來,用Xcode打開并運行它。

APP的UI部分已經完成了大部分,但這個APP的核心功能依賴與正則表達式,這個還沒有…!你的任務就是添加正則表達式來時這個APP更出色。

下面所視的幾個截圖的例子展示了這個應用的內容:


1428995296861821.png

這個簡單的應用涵蓋兩個正則表達式的通用用例:
1.執行搜索:高亮顯示搜索和替換
2.驗證用戶輸入

這就開始直接使用正則表達式:文本搜索

  • /Search( and replace)?/

這是一個搜索/替換的簡單功能的概述:

搜索視圖控制器SearchViewController 有一個只讀的UITextView,其內容是《傲慢與偏見》的一個片段。
navigation bar包含一個搜索按鈕,點擊會呈現一個模態的SearchOptionsViewController。
用戶輸入一些信息并點擊“Search”按鈕。
APP會隱藏這個search view 并高亮顯示textview中所有匹配的內容。
如果用戶選擇了SearchOptionsViewController中的“Replace”選項,APP會執行搜索并替換文本中所有匹配的內容,不再是高亮顯示結果。
Note:你的APP會用到UITextView的NSAttributedString屬性來高亮顯示搜索的結果。更多這方面的內容請參考 iOS 6 by Tutorials的第15章--“What’s New with Attributed Strings”。

你也可以用text kit來實現高亮的功能。確保找到Text Kit Tutorial in Swift 來查看更多內容。

還有一個“Bookmark”按鈕,允許用戶高亮顯示文本中的日期,時間,位置。為簡單起見,不會涵蓋文本中出現的各種格式的日期時間位置。在教程的結尾你可以實現這個高亮功能。

開始實現這個功能的第一步是跳轉到標準字符串正則表達式的NSRegularExpression對象。

打開SearchOptionsViewController.swift。SearchViewController模態顯示這個view controller,且允許用戶鍵入他們的搜索條件,也可以指定是否區分大小寫。

看一下文件頭部的SearchOptions結構體,SearchOptions是一個封裝了用戶搜索選項的簡答結構體。代碼傳遞SearchOptions的一個實例給SearchViewController。它用這種方式很好的構造一個合適的NSRegularExpression,你可以通過運用擴展自定義的NSRegularExpression來實現。

選擇File > New > File… 選擇Swift File,命名為RegexHelpers.swift。打開新建的文件并添加如下代碼:

extension NSRegularExpression {
  convenience init?(options: SearchOptions) {
    let searchString = options.searchString
    let isCaseSensitive = options.matchCase
    let isWholeWords = options.wholeWords
  
    let regexOption: NSRegularExpressionOptions = (isCaseSensitive) ? .allZeros : .CaseInsensitive
  
    let pattern = (isWholeWords) ? "\\b\(searchString)\\b" : searchString
  
    self.init(pattern: pattern, options: regexOption, error: nil)
  }
}

代碼為NSRegularExpression增加了一個便利構造方法。它通過SearchOptions實例的不同設置來做一些正確的配置。

當用戶請求一個不區分大小寫的搜索,正則表達式使用.CaseInsensitive的CaseInsensitiveNSRegularExpressionOptions值。NSRegularExpression默認是區分大小寫的,這個例子中,你使用的是更有好的不區分大小寫。
如果用戶請求一個完整的單詞,APP把正則表達式包含在\b字符組之內。在單詞邊界字符組中放入\b,因此,搜索模式之前和之后加上\b就會返回一個完整的單詞搜索(舉例來說,模式“\bcat\b”只會匹配單詞“cat”,而不會匹配“catch”)。
如果以任何理由都不能創建NSRegularExpression,構造函數就會失敗并返回nil。既然你有了NSRegularExpression對象,你就能伴隨著其他操作來匹配文本了。

打開SearchViewController.swift,找到searchForText,用下面的代碼替換它。

func searchForText(searchText: String, replaceWith replacementText: String, inTextView textView: UITextView) {
  let beforeText = textView.text
  let range = NSMakeRange(0, countElements(beforeText))
  
  if let regex = NSRegularExpression(options: self.searchOptions!) {
    let afterText = regex.stringByReplacingMatchesInString(beforeText, options: .allZeros, range: range, withTemplate: replacementText)
  
    textView.text = afterText
  }
}

首先,這個方法捕獲UITextView中得當前文本,并計算文本的長度。可能會把正則表達式應用在文本的一個子集上,所以你需要指定一個范圍。這種情況下,你要用字符串的整個長度才能保證正則表達式被運用在整個文本上。

不可思議的事發生在調用stringByReplacingMatchesInString的時候。這個方法返回一個新字符串并沒有改變舊字符串。然后,這個方法給UITextView設置這個新字符串,所以用戶看到了正確的結果。

繼續留在SearchViewController,找到highlightText,用下面的代碼替換它。

func highlightText(searchText: String, inTextView textView: UITextView) {
  // 1 
  let attributedText = textView.attributedText.mutableCopy() as NSMutableAttributedString
  // 2
  let attributedTextRange = NSMakeRange(0, attributedText.length)
  attributedText.removeAttribute(NSBackgroundColorAttributeName, range: attributedTextRange)
  // 3
  if let regex = NSRegularExpression(options: self.searchOptions!) {
    let range = NSMakeRange(0, countElements(textView.text))
    let matches = regex.matchesInString(textView.text, options: .allZeros, range: range)
   // 4
    for match in matches as [NSTextCheckingResult] {
      let matchRange = match.range
  
      attributedText.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellowColor(), range: matchRange)
    }
  }
  // 5
  textView.attributedText = attributedText.copy() as NSAttributedString
}

這兒就一步一步的解釋上面的代碼:

1.首先,得到一個textview的attributedText的可變拷貝,

2.然后,創建一個整個文本長度的NSRange,并刪除已經有背景色的文本的背景色,

3.正如找到和替換,緊接著用你的便利構造方法創建一個正則表達式,獲取一個存放正則表達式與textview中文本匹配的所有匹配項的數組。

  1. 輪詢每一個匹配項(把它們轉換成NSTextCheckingResult對象),并為每一項添加黃色背景。

5.最后,用高亮的結果更新UITextView。

編譯和運行你的APP,試著搜索一些不同的單詞和詞組!整個文本的匹配項都會高亮顯示,就像下面的圖片所示:

1428995793122575.png

試著使用不同的選項(options)搜索單詞“the”看看效果。注意,例如,當搜索整個單詞時,‘them’中得‘the’不會高亮顯示。
再者,測試一下搜索和替換功能,看看你的文本字符串是怎樣如期替換的,試一下’match case‘和‘whole words’選項。

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

推薦閱讀更多精彩內容

  • 正則表達式又稱為正規表示法、規則表達式、常規表示法,英語為Regular Expression,常簡寫為regex...
    pro648閱讀 5,443評論 1 11
  • 參考:正則表達式、正則表達式30分鐘入門教程、正則表達式的使用方法 一、概述 正則表達式(Regular Expr...
    夏天的風_song閱讀 2,292評論 0 1
  • iOS中使用正則表達式就不得不提NSRegularExpression,所以我們需要先搞清楚什么是NSRegula...
    sunmumu1222閱讀 2,365評論 0 4
  • 推薦幾個正則表達式編輯器 Debuggex :https://www.debuggex.com/ PyRegex:...
    木易林1閱讀 11,526評論 9 151
  • 夏日的午后,云淡風輕。 微風,只有樹葉輕輕晃動。 安靜的世界,美的不像話。 前方是綿延的山巒 身后是恬靜的村莊 小...
    紅玫瑰和白汽球閱讀 328評論 0 0