主要问题:当我的模式为 时,ObjC 可以告诉我有六个匹配项@"\\b(\\S+)\\b"
,但是当我的模式为 时@"A b (c) or (d)"
,它只报告一个匹配项,"c"
。
解决方案
这是一个将捕获组作为 NSArray 返回的函数。我是一个 Objective C 新手,所以我怀疑有比创建一个可变数组并在最后将其分配给 NSArray 更好的方法来完成笨重的工作。
- (NSArray *)regexWithResults:(NSString *)haystack pattern:(NSString *)strPattern
{
NSArray *ar;
ar = [[NSArray alloc] init];
NSError *error = NULL;
NSArray *arTextCheckingResults;
NSMutableArray *arMutable = [[NSMutableArray alloc] init];
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:strPattern
options:NSRegularExpressionSearch error:&error];
arTextCheckingResults = [regex matchesInString:haystack
options:0
range:NSMakeRange(0, [haystack length])];
for (NSTextCheckingResult *ntcr in arTextCheckingResults) {
int captureIndex;
for (captureIndex = 1; captureIndex < ntcr.numberOfRanges; captureIndex++) {
NSString * capture = [haystack substringWithRange:[ntcr rangeAtIndex:captureIndex]];
//NSLog(@"Found '%@'", capture);
[arMutable addObject:capture];
}
}
ar = arMutable;
return ar;
}
问题
我习惯于使用括号来匹配 Perl 中的捕获组,如下所示:
#!/usr/bin/perl -w
use strict;
my $str = "This sentence has words in it.";
if(my ($what, $inner) = ($str =~ /This (\S+) has (\S+) in it/)) {
print "That $what had '$inner' in it.\n";
}
该代码将产生:
那句话里有“词”。
但是在 Objective C 中,使用 NSRegularExpression,我们会得到不同的结果。示例功能:
- (void)regexTest:(NSString *)haystack pattern:(NSString *)strPattern
{
NSError *error = NULL;
NSArray *arTextCheckingResults;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:strPattern
options:NSRegularExpressionSearch
error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:haystack options:0 range:NSMakeRange(0, [haystack length])];
NSLog(@"Pattern: '%@'", strPattern);
NSLog(@"Search text: '%@'", haystack);
NSLog(@"Number of matches: %lu", numberOfMatches);
arTextCheckingResults = [regex matchesInString:haystack options:0 range:NSMakeRange(0, [haystack length])];
for (NSTextCheckingResult *ntcr in arTextCheckingResults) {
NSString *match = [haystack substringWithRange:[ntcr rangeAtIndex:1]];
NSLog(@"Found string '%@'", match);
}
}
调用该测试函数,结果显示它能够计算字符串中的单词数:
NSString *searchText = @"This sentence has words in it.";
[myClass regexTest:searchText pattern:@"\\b(\\S+)\\b"];
模式:'\b(\S+)\b' 搜索文本:“这句话中有单词。” 比赛次数:6 找到字符串 'This' 找到字符串“句子” 找到字符串“有” 找到字符串“单词” 找到字符串 'in' 找到字符串“它”
但是如果捕获组是明确的,像这样呢?
[myClass regexTest:searchText pattern:@".*This (sentence) has (words) in it.*"];
结果:
模式:'.*这个(句子)里面有(单词)。*' 搜索文本:“这句话中有单词。” 匹配数:1 找到字符串“句子”
与上面相同,但使用 \S+ 而不是实际单词:
[myClass regexTest:searchText pattern:@".*This (\\S+) has (\\S+) in it.*"];
结果:
模式:'.*这个 (\S+) 里面有 (\S+)。*' 搜索文本:“这句话中有单词。” 匹配数:1 找到字符串“句子”
中间的通配符怎么样?
[myClass regexTest:searchText pattern:@"^This (\\S+) .* (\\S+) in it.$"];
结果:
模式:'^This (\S+) .* (\S+) in it.$' 搜索文本:“这句话中有单词。” 匹配数:1 找到字符串“句子”
参考: NSRegularExpression NSTextCheckingResult NSRegularExpression 匹配选项