NSRegularExpression enumerateMatchesInString:[...] usingBlock永远不会停止

时间:2012-08-09 18:37:35

标签: objective-c ios regex

我正在调用上面提到的函数,它正在迭代所有匹配。但是,在处理完所有匹配的块之后,它没有完成执行。我可能做错了什么?

使用的正则表达式为:/\[([^\[\{,]*(,\n)?)*\]/

2 个答案:

答案 0 :(得分:4)

从您对自己问题的回答来看,您似乎通过传递NSMatchingReportCompletion来解决问题。我怀疑你可能已经治愈了一种症状,而不是疾病。

我想知道您是否可能意外地将错误的options值传递给enumerateMatchesInString。例如,很容易错误地调用它:

[regex enumerateMatchesInString:stringToSearch
                        options:NSRegularExpressionCaseInsensitive
                          range:NSMakeRange(0, [stringToSearch length])
                     usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
                         // This is called many times, 
                         // even when there is no match!
                     }];

乍一看,这看起来很好,编译器没有抱怨,但我们得到了块被调用太多次的不良行为,通常是result == nil

您可以通过将NSMatchingReportCompletion添加到options来解决此问题,而不是多次调用该块,它仅在匹配时调用,并在完成时再次调用。这解决了它,但它是一个不优雅的解决方案,忽视了问题的根源。

问题是,NSRegularExpressionCaseInsensitive根本不是options的{​​{1}}参数的适当值... enumerateMatchesInString的{​​{1}}值。更糟糕的是,options恰好与regularExpressionWithPattern相同,后者会生成您描述的行为。

正确的解决方案是简单地传递NSRegularExpressionCaseInsensitive NSMatchingReportProgress的值,如下所示,options仅针对匹配进行调用,而不是针对临时进度而不是完成时:

0

答案 1 :(得分:0)

我已通过传递NSMatchingReportCompletion作为选项并在匹配为零时将stop设置为YES来解决此问题。