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阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 正则表达式又称为正规表示法、规则表达式、常规表示法,英语为Regular Expression,常简写为regex...
    pro648阅读 5,368评论 1 11
  • 参考:正则表达式、正则表达式30分钟入门教程、正则表达式的使用方法 一、概述 正则表达式(Regular Expr...
    夏天的风_song阅读 2,260评论 0 1
  • iOS中使用正则表达式就不得不提NSRegularExpression,所以我们需要先搞清楚什么是NSRegula...
    sunmumu1222阅读 2,331评论 0 4
  • 推荐几个正则表达式编辑器 Debuggex :https://www.debuggex.com/ PyRegex:...
    木易林1阅读 11,458评论 9 151
  • 夏日的午后,云淡风轻。 微风,只有树叶轻轻晃动。 安静的世界,美的不像话。 前方是绵延的山峦 身后是恬静的村庄 小...
    红玫瑰和白汽球阅读 315评论 0 0