如何加快与NSRegularExpression iPhone正则expression式?

我的iPhone应用程序使用正则expression式(与NSRegularExpression)来执行计算大量的string(在1000年)。 这当然需要很多时间。 什么是加快正则expression式的一些策略? 我研究了使用块,但我不认为它会有什么好处 – 它们似乎主要代表lambdafunction(即相当于lisp),并且在具有多个内核的Mac上使用。 显然,目前的iPhone没有多核心。

这是我的代码:

NSString *replaceRegexPattern = @"([\\(|\\[].*?[\\)|\\]])|(^to )"; NSRegularExpression *replaceRegex = [[NSRegularExpression regularExpressionWithPattern:replaceRegexPattern options:NSRegularExpressionCaseInsensitive error:nil] retain]; NSArray *myArray = <some data>; NSString *myString, *compareValue; for (i = 0; i < [myArray count]; i++) { myString = [myArray objectAtIndex:i]; compareValue = [replaceRegex stringByReplacingMatchesInString:myString options:0 range:NSMakeRange(0, [myString length]) withTemplate:@""]; // do things with compareValue } 

为了回答下面的问题,我在这个代码中的目标是删除我的string中的任何文字,这些文字用圆括号括起来,或者以“to”开头。 这里有些例子:

  • 你好(再见) – >你好
  • 你好(再见[n]) – >你好
  • 说 – >说
  • 说(pf) – >说

既然我不知道你到底在做什么,很难给出有根据的build议,但看起来你的正则expression式可能会有所改进。

你真的想匹配像(foo)[bar]|baz|这样的string ? 你不需要| 交stream发电机里面的字符类,所以除非你想匹配这里的第三个例子,那么放下| 秒。

然后,因为你期待像(foo [bar] baz)这样的string,所以你需要分开两种括号,并且你还可以加快你的正则expression式:

 @"^to |\\([^)]*\\)|\\[[^\\]]*\\]" 

这首先检查string的开头,然后寻找一个开放的paren /托架,除了closuresparens /托架,以及一个closures的托架/托架。 这需要更less的回溯,所以它可能快一点。

你将无法处理同样types的( (foo (bar) baz) )的嵌套圆括号/括号,因为这不是正规的 – 除非你多次运行正则expression式replace操作,筑巢。 所以上面的例子将被删除,如果你运行正则expression式replace两次。

你确定正则expression式是正确的工具吗?

如果你所要做的只是删除括号内的文本,通过string的一个简单的char-by-char循环可以很容易地完成,甚至可以正确地处理嵌套的parens。

在伪代码中:

  nesting_level = 0; while more_chars { c = next_char; if c == '(' or c == '[') ++nesting_level; else if c == ')' or c == ']' --nesting_level; // check for nesting_level < 0 here? else if nesting_level == 0 result += c; } 

很明显,做你自己的基准testing,但是可能通过避免正则expression式来获得更好的性能。

(如果你关心检测像“(你好)”这样的不规则的东西,你可以添加简单的recursion下降到这个)

加速这个正则expression式的最好方法是使用所有格量词:

 NSString *replaceRegexPattern = @"^to\\s++|\\[[^\\[\\]]*+\\]|\\([^()]*+\\)"; 

如果因为左括号与正确的右括号不匹配而导致不匹配, *+防止我们知道的回溯将毫无意义。 但成功的匹配尝试也更有效率,因为正则expression式引擎不必保存使回溯成为可能的状态信息。

正如Tim指出的那样,这将不匹配相同types括号的嵌套实例,如((foo))[[bar]] 。 它将匹配匹配括号内的任意数目的方括号,反之亦然。 例如,它不需要将这些内括号正确配对,因此它将匹配(foo[)[(bar))] 。 您的原始正则expression式也是如此。

在字符类中包含开头的括号可防止[[foo]((bar)等不平衡匹配。