Основная проблема: 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";
}
Этот код будет производить:
That sentence had 'words' in it.
Но в Цели 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"];
Pattern: '\b(\S+)\b'
Search text: 'This sentence has words in it.'
Number of matches: 6
Found string 'This'
Found string 'sentence'
Found string 'has'
Found string 'words'
Found string 'in'
Found string 'it'
Но что еслигруппы захвата явные, как так?
[myClass regexTest:searchText pattern:@".*This (sentence) has (words) in it.*"];
Результат:
Pattern: '.*This (sentence) has (words) in it.*'
Search text: 'This sentence has words in it.'
Number of matches: 1
Found string 'sentence'
То же, что и выше, но с \ S + вместо реальных слов:
[myClass regexTest:searchText pattern:@".*This (\\S+) has (\\S+) in it.*"];
Результат:
Pattern: '.*This (\S+) has (\S+) in it.*'
Search text: 'This sentence has words in it.'
Number of matches: 1
Found string 'sentence'
Как насчет подстановочного знака в середине?
[myClass regexTest:searchText pattern:@"^This (\\S+) .* (\\S+) in it.$"];
Результат:
Pattern: '^This (\S+) .* (\S+) in it.$'
Search text: 'This sentence has words in it.'
Number of matches: 1
Found string 'sentence'
Ссылки: NSRegularExpression NSTextCheckingResult Параметры соответствия NSRegularExpression