gpt4 book ai didi

objective-c - 为什么 NSRegularExpression 在所有情况下都不支持捕获组?

转载 作者:搜寻专家 更新时间:2023-10-30 19:56:45 25 4
gpt4 key购买 nike

主要问题:当我的模式是 @"\\b(\\S+)\\b" 时,ObjC 可以告诉我有六个匹配项,但是当我的模式是 @ 时"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.

But in Objective C, with NSRegularExpression, we get different results. Sample function:

- (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'

But what if the capture groups are explicit, like so?

[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'

Same as above, but with \S+ instead of the actual words:

[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'

How about a wildcard in the middle?

[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 matching options

最佳答案

我想如果你改变

// returns the range which matched the pattern
NSString *match = [haystack substringWithRange:ntcr.range];

// returns the range of the first capture
NSString *match = [haystack substringWithRange:[ntcr rangeAtIndex:1]];

对于包含单个捕获的模式,您将获得预期的结果。

请参阅 NSTextCheckingResult:rangeAtIndex 的文档页面:

结果必须至少有一个范围,但也可以有更多范围(例如,表示正则表达式捕获组)。

传递 rangeAtIndex:值 0 始终返回 range 属性的值。其他范围(如果有)的索引将从 1 到 numberOfRanges-1。

关于objective-c - 为什么 NSRegularExpression 在所有情况下都不支持捕获组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7600103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com