iOS 开发中使用正则表达式-暨 RegexKitLite 库的用法

在 iOS 开发中要用正则表达式的话,至少有三种选择:

1. 系统自带的  NSString 和 NSMutableString 相关的方法
2. RegexKit Framework - http://regexkit.sourceforge.net
3. RegexKitLite - http://regexkit.sourceforge.net/RegexKitLite/

NSString 和 NSMutableString 里像

带有 NSStringCompareOptions 参数的方法就可以支持正则表达式,只要对于 NSStringCompareOptions 参数取值中含有 NSRegularExpressionSearch 这个 Mask 值即可。

RegexKit Framework 用的是 PCRE(Perl Compatible Regular Expressions) 库,可能是我们熟悉正则表达式语法,但需要引入 PCRE 静态库。

RegexKitLite,看链接它与 RegexKit Framework 出自一家,但它用的是 Mac 自带的 ICU(International Components for Unicode) 库,所以语法上与 RegexKit Framework 是不一样的,且引入它也较简单。

只要下载到文件 RegexKitLite-4.0.tar.bz2,解压出其中的 RegexKitLite.h 和 RegexKitLite.m 两文件加到项目中来,再就记得加上系统自带的 libicucore.dylib 库就行。RegexKitLite 所有的方法也是对 NSString 和 NSMutableString 两个类的扩展方法,典型的方法:

真要说 RegexKitLite 的用法,也就又回到了正则表达式的写法,没什么可说的,只要参考:http://regexkit.sourceforge.net/RegexKitLite/,里面也有所有的扩展方法列表。

因此,这里只说一个如何进行不区分大小写的匹配,沿袭以往的经验,要么向 JS 那样 /abc/i,要么就是加上不区分大小写的标识参数,如:

中的 (RKLRegexOptions)options 参数,可以支持:

RKLNoOptions, RKLCaseless, RKLComments, RKLDotAll, RKLMultiline, RKLUnicodeWordBoundarie

这个组合,只要标识上 RKLCaseless。然而你也许发现了如果不区分大小写的匹配,调用方法只是:

就因为要支持大小写不敏感而必须用另一个参数多几个的重载方法,要是想要应用 replaceOccurrencesOfRegex 方法,大小写不敏感比不敏感的方法版本参数多的更多,实际并不用关心那些多余的参数,甚是不便。

那么能不能像 JS 的正则表达式那样把约束标识写在正则表达式里呢,可以的,请试一下:

会输出 Matched,匹配成功,关键就是表达式中的 (?i)Xxx 或者 (?i:Xxx) 表明这个表达式不区分大小写,可以查看下这个帮助原文:


Options for controlling the behavior of a regular expression pattern can be controlled in two ways. When the method supports it, options may specified by combining RKLRegexOptions flags with the C bitwise OR operator. For example:

matchedRange = [aString rangeOfRegex:@"^(blue|red)$" options:(RKLCaseless | RKLMultiline) inRange:range error:NULL];

The other way is to specify the options within the regular expression itself, of which there are two ways. The first specifies the options for everything following it, and the other sets the options on a per capture group basis. Options are either enabled, or following a -, disabled. The syntax for both is nearly identical:

Option Example Description
(?ixsmw-ixsmw)… (?i)… Enables the RKLCaseless option for everything that follows it. Useful at the beginning of a regular expression to set the desired options.
(?ixsmw-ixsmw:…) (?iw-m:…) Enables the RKLCaseless and RKLUnicodeWordBoundaries options and disables RKLMultiline for the capture group enclosed by the parenthesis.

The following table lists the regular expression pattern option character and its corresponding RKLRegexOptions flag:

Character Option
i RKLCaseless
x RKLComments
s RKLDotAll
m RKLMultiline
w RKLUnicodeWordBoundaries

上面就是说对正则表达式的控件可以有两种选择,用 RKLRegexOptions 标识,或在表达式中用 (?..) 的写法。第二种选择又有两种写法,一种是 (?i)...  和 (?i:...)。问号后支持 i、x、s、m 和 w 五个标识,各自的意义看上面的表格,在标识前加个减号 - 表示去除该特性。

附上一些常用的 ICU 格式正则表达式:

Network and URL

Description Regex
HTTP \bhttps?://[a-zA-Z0-9\-.]+(?:(?:/[a-zA-Z0-9\-._?,'+\&%$=~*!():@\\]*)+)?
HTTP \b(https?)://([a-zA-Z0-9\-.]+)((?:/[a-zA-Z0-9\-._?,'+\&%$=~*!():@\\]*)+)?
HTTP \b(https?)://(?:(\S+?)(?::(\S+?))?@)?([a-zA-Z0-9\-.]+)(?::(\d+))?((?:/[a-zA-Z0-9\-._?,'+\&%$=~*!():@\\]*)+)?
E-Mail \b([a-zA-Z0-9%_.+\-]+)@([a-zA-Z0-9.\-]+?\.[a-zA-Z]{2,6})\b
Hostname \b(?:[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}?[a-zA-Z0-9]\.)+[a-zA-Z]{2,6}\b
IP \b(?:\d{1,3}\.){3}\d{1,3}\b
IP with Optional Netmask \b((?:\d{1,3}\.){3}\d{1,3})(?:/(\d{1,2}))?\b
IP or Hostname \b(?:(?:\d{1,3}\.){3}\d{1,3}|(?:[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}?[a-zA-Z0-9]\.)+[a-zA-Z]{2,6})\b

上面的正则表达式实际书写时需把一个反斜杠替换成两个反斜杠,如匹配 E-Mail 时要写成

上面的代码输出:

Regex: \b([a-zA-Z0-9%_.+\-]+)@([a-zA-Z0-9.\-]+?\.[a-zA-Z]{2,6})\b
Valid email address

这和 Java 的正则表达式一样,也就是要写成 NSLog 输出的样子,也就是转义的转义,如果是 \- 或 \. 编译时会提示:

Lexical or Preprocessor Issue Unknown escape sequence "\."
Lexical or Preprocessor Issue Unknown escape sequence "\-"

但执行时不会报错,只是匹配不成功.

记住,RegexKitLite 的完全帮助手册尽在:http://regexkit.sourceforge.net/RegexKitLite/

类别: iOS. 标签: , . 阅读(3,461). 订阅评论. TrackBack.

Leave a Reply

Be the First to Comment!

avatar