【问题标题】:How can NSRegularExpression give me a NSRange out of bounds?NSRegularExpression 如何给我一个 NSRange 越界?
【发布时间】:2018-05-30 11:32:06
【问题描述】:

我正在使用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
}

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

【问题讨论】:

  • 很难在摘要中说出发生了什么。您能否创建一个包含示例数据的最小示例项目来展示问题并将其发布到 Github 之类的地方?
  • 当你崩溃时匹配为零吗?在这种情况下,在 Objective-C 中,numberOfRanges 将作为 nil 出现,for 循环将执行一次并崩溃。在我看来,您需要在块的顶部使用 if (match == nil) { return } 来测试这种情况。
  • @DuncanC - 好的,但是当 numberOfRanges 大于 0 时,如何解释 NSRange 等于 nil?

标签: ios objective-c cocoa cocoa-touch nsregularexpression


【解决方案1】:

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

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

及其匹配的字符串:

a
bd
bcd

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

正是这个“不匹配”范围给了你错误,因为你没有检查它。

HTH

【讨论】:

  • 感谢您的解释。我认为如果 3 个条件匹配,NSRegularExpression 只会考虑匹配,但事实并非如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-04
  • 2012-06-13
  • 1970-01-01
  • 2020-06-25
  • 1970-01-01
  • 2019-04-06
  • 1970-01-01
相关资源
最近更新 更多