您的位置:首页 > 移动开发 > IOS开发

IOS NSRegularExpression 解析正则表达式

2012-09-18 22:11 274 查看
iOS 中可以通过 NSPredicate 来处理正则表达式。相关资料如下:

NSPredicate 苹果官方文档:

http://developer.apple.com/documentation/Cocoa/Conceptual/Predicates/predicates.html

Predicate format strings:

http://developer.apple.com/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html

ICU 正则表达式规则:

http://www.icu-project.org/userguide/regexp.html

在 iOS 中,我们使用 NSPredicate 的字符串比较功能来进行正则表达式处理,其比较关键字为:
MATCHES


下面,列举一个匹配6-15个由字母/数字组成的字符串的正则表达式,来看看 NSPredicate 的具体使用:

NSString * regex= @"(^[A-Za-z0-9]{6,15}$)";
NSPredicate * pred  = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
BOOL isMatch= [pred evaluateWithObject:@"123456ABCde"];


初始化一个 NSRegularExpression 对象 注:_str是要匹配的字符串

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"http://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?" options:NSRegularExpressionCaseInsensitive error:nil];

获得所有匹配了表达式的字符串。

NSArray *array =nil;

array = [regex matchesInString:_str options:0 range:NSMakeRange(0, [_str length])];

NSString *str1 = nil;

for (NSTextCheckingResult* b in array)

{

str1 是每个和表达式匹配好的字符串。

str1 = [_str substringWithRange:b.range];

NSLog(@" str 1 is %@",str1);

}

获得匹配的字符串的个数

NSUInteger numberOfMatches = [regex numberOfMatchesInString:_str options:0 range:NSMakeRange(0, [_str length])];

替换匹配的字符串 $0很重要 $0不行的话 $1依此类推 打印了看结果

NSString *modifiedString = [regex stringByReplacingMatchesInString:_str

options:0

range:NSMakeRange(0, [_str length])

withTemplate:@"<a href=\"$0\">$0</a>"];

NSLog(@"######## the modified string is %@",modifiedString);

2.

NSString *regExStr =@"<input type='hidden' id='([G|U]{1})(\\d+)' value='(.*?)'>";

NSError *error =
NULL;

NSRegularExpression *regex = [NSRegularExpressionregularExpressionWithPattern:regExStr
options:NSRegularExpressionCaseInsensitiveerror:&error];

[regexenumerateMatchesInString:addressBookString
options:0
range:NSMakeRange(0, [addressBookStringlength])
usingBlock:^(NSTextCheckingResult *regResult,NSMatchingFlags flags,
BOOL *stop) {

NSString *type = [NSStringstringWithString:[addressBookString
substringWithRange:[regResult
rangeAtIndex:1]]];
NSString *nameID = [NSStringstringWithString:[addressBookString
substringWithRange:[regResult
rangeAtIndex:2]]];
NSString *name = [NSStringstringWithString:[addressBookString
substringWithRange:[regResult
rangeAtIndex:3]]];

if([type
isEqualToString:@"G"]){
AddressBookNode *addressBookNode = [[AddressBookNodealloc]init];
addressBookNode.isDirectory =TRUE;
addressBookNode.nodeLevel =1;
addressBookNode.nodeName = name;
addressBookNode.nodeID = nameID;
[addressBookaddChild:addressBookNode];

}else{
AddressBookNode *addressBookNode = [[AddressBookNodealloc]init];
addressBookNode.isDirectory =FALSE;
addressBookNode.nodeLevel =1;
addressBookNode.nodeName = name;
addressBookNode.nodeID = nameID;
[addressBookaddChild:addressBookNode];

}

}];

3.

char
*utf8CString
=
"test;;;
test2 what are you doing, now?"
;
06
NSString
*regexString =
@";"
;
07
NSString
*sourceString = [NSString stringWithUTF8String:utf8CString];
08
NSString
*resultString = [sourceString stringByReplacingOccurrencesOfRegex:regexString withString:
@"_"
];
09
 
10
NSLog(
@"sourceString:
\"
%@\"",
sourceString);
11
NSLog(
@"resultString:
\"
%@\"",
resultString);
12
 
13
char
*utf8CString1
=
"Copyright
\xC2\xA9 \xE2\x89\x85 2008"
;
14
NSString
*regexString1 =
@"Copyright
(.*) (\\d+)"
;
15
NSString
*sourceString1 = [NSString stringWithUTF8String:utf8CString1];
16
NSString
*resultString1 = [sourceString1 stringByMatching:regexString1 capture:1L];
17
 
18
NSLog(
@"sourceString:
\"
%@\"",
sourceString1);
19
NSLog(
@"resultString:
\"
%@\"",
resultString1);
20
 
21
char
*utf8CString2
=
"One\t
Two \tThree "
;
22
NSString
*source = [NSString stringWithUTF8String:utf8CString2];
23
NSString
*result = [source stringByReplacingOccurrencesOfRegex:
@"\\s+"
withString:
@"
"
];
24
 
25
NSLog(source);
26
NSLog(result);
27
 
28
NSString
*source1 =
@"Test;12;Y"
;
29
NSArray
*columns = [source1 componentsSeparatedByRegex:
@";\\s*"
];
30
 
31
NSLog([columns
description]);
32
 
33
NSString
*source2 =
@"<foo
no=\"
12\">Name</foo>";
34
NSString
*regex2 =
@"<foo
no=\"
(.+?)\">(.*?)</foo>";
35
int
no
= [[source2 stringByMatching:regex2 capture:1] intValue];
36
NSString
*data = [source2 stringByMatching:regex2 capture:2];
37
 
38
NSLog(
@"no:
%d data: %@"
,
no, data);
在 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 combiningRKLRegexOptions 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:
OptionExampleDescription
(?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:
CharacterOption
iRKLCaseless
xRKLComments
sRKLDotAll
mRKLMultiline
wRKLUnicodeWordBoundaries
上面就是说对正则表达式的控件可以有两种选择,用 RKLRegexOptions 标识,或在表达式中用 (?..) 的写法。第二种选择又有两种写法,一种是 (?i)... 和 (?i:...)。问号后支持 i、x、s、m 和 w 五个标识,各自的意义看上面的表格,在标识前加个减号 - 表示去除该特性。

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


Network and URL

DescriptionRegex
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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: