NSRegularExpression 如何给我一个 NSRange 越界?

How can NSRegularExpression give me a NSRange out of bounds?

我正在使用 NSRegularExpression 查找文本中出现的字符串。像这样:

  NSRegularExpression *regex = [NSRegularExpression
                                regularExpressionWithPattern:@"<a href=\"(.*)\">(.*)</a>[:blank:]|[:blank:](.*)\n\n\n"
                                options:NSRegularExpressionCaseInsensitive
                                error:&error];

然后,我用这个枚举结果:

  [regex enumerateMatchesInString:textContent options:0 range:NSMakeRange(0, [textContent length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop){

  }];

在块内,因为结果可以有多个范围,所以我有这些行:

NSInteger numberOfRanges = [match numberOfRanges];

// then I enumerate the ranges

for (int i=0; i<[match numberOfRanges]; i++) {
  NSRange range = [match rangeAtIndex:i];
  // The problem here is that some ranges come out of bounds
}

问题是在枚举范围时,有些超出范围。如果这些范围是由代码本身找到的,那怎么可能???

问问自己,当正则表达式中带括号的表达式什么都不匹配时会发生什么?例如,考虑 RE:

(a)|(b)(c)?(d)

及其匹配的字符串:

a
bd
bcd

现在在 RE 中 总是 四个带括号的表达式,因此 numberOfRanges 将始终为 4,即使它们不可能全部匹配某些东西(由于或|)。那么对于不匹配任何内容的范围返回什么?检查 NSRegularExpression 的文档,您会发现它是范围 {NSNotFound, 0},即 location 成员的值为 NSNotFound.

正是这个 "no match" 范围给了你错误,因为你没有检查它。

HTH