iPhone:RegexKit vs. RegexKit lite - 通过数组需要很长时间

时间:2009-08-06 19:13:14

标签: iphone objective-c regex

对于我的应用程序,我需要查看url是否与正则表达式字符串匹配。所以我创建了一个包含所有正则表达式字符串(大约1000多个字符串)的数组,并使用RegexKit lite检查它们:

for (NSString * aString in mainDelegate.whiteListArray) {

if (![urlString isMatchedByRegex:aString]) {

它有效,但遗憾的是这个操作需要很长时间。对于像google.com这样的网页至少需要20秒

我尝试过使用“普通”RegexKit.framework,因为它有一个名为(BOOL)的方法isMatchedByAnyRegexInArrayNSArray *)regexArray要快得多。我可以构建应用程序,但每当我尝试启动它时崩溃都会出现以下错误:

  

dyld:未加载库:@executable_path /../ Frameworks / RegexKit.framework / Versions / A / RegexKit   参考自:/ Users / Reilly / Library / Application Support / iPhone Simulator / User / Applications / 7E057EA8-5CD1-465B-8102-38A53A9B5F5B / Drowser.app / Drowser   原因:未找到图像

我想这是因为RegexKit不适合手臂? (包括RegexKit我遵循文档中的方法)

所以我的问题是:

  1. 如果字符串被1000个正则表达式中的任何一个匹配,您知道检查字符串的更快方法。

  2. 或者你知道如何在iPhone或任何其他正则表达框架上使用“普通”RegexKit,它会在一秒钟内完成我需要的工作吗?

  3. 提前致谢

3 个答案:

答案 0 :(得分:8)

注意:我是RegexKit等人的作者。

这是一个相当复杂的答案.. :)

首先,将一千个正则表达式与任何常用的正则表达式引擎实现相匹配将会相当慢,除了TCL和TRE正则表达式引擎。 RegexKit.framework为此任务大大优于RegexKitLite的原因RegexKit.framework为此任务提供了相当多的非平凡,优化的代码。这是因为它在Safari AdBlock中使用,它需要针对URL执行正则表达式的批量匹配。它根据成功匹配的次数,按照排序顺序保留正则表达式列表。这是基于以下观察:Safari AdBlock中使用的一些正则表达式模式比其他模式更频繁地匹配,并且首先尝试这些模式会显着减少需要尝试的正则表达式的数量,以确定是否存在“命中”。还有一个小的负面命中缓存,以及许多多线程代码来并行执行匹配。这些都不会进入Lite版本,因为它绝对不是一个轻量级的功能 - 可能只有60-70KB的代码才能单独实现这一功能,更不用说大量的内存占用了保持一千个编译的正则表达式。

使用RegexKitLite进行这种模式匹配必然非常非常慢。第一个问题是它只保留了最近使用过的编译正则表达式的小缓存。默认情况下,缓存设置为23,因此抛出一千个正则表达式会导致每次使用正则表达式进行编译。

正如其他人所指出的,RegexKit.framework并未真正设置为在iPhone上使用。即使您使用了“链接到外部框架”规定,RegexKit.framework的默认构建也不包含其胖二进制文件中的arm体系结构(包括ppc,{{1} },ppc64i386)。您真正需要做的是设置一个新的构建目标,以创建一个静态库。真的不是很难做到。

我担心如果这种模式匹配是你需要做的事情,你可能不得不推出自己的正则表达式引擎。你需要的是一个正则表达式引擎,它可以将你的千个正则表达式连接在一起,例如“x86_64”。大多数正则表达式引擎,特别是r1|r2|r3|r4pcre(分别由ICURegexKit.framework使用的引擎),以几乎从左到右的方式评估这样的正则表达式。我们需要的是几乎类似于DFA的引擎,它可以同时评估所有可能的状态。有关详细信息,请参阅this link。我已经构建了一个这样的正则表达式引擎,甚至可以在〜RegexKitLite中处理后向引用(比每个人都要容易得多)(M是要匹配的文本的大小,N是正则表达式的大小) )时间,但它没有完成。如果是这样的话,就会像等离子火炬一样切断这种问题。

我知道至少有一个人将O(M*log2(N))移植到iPhone上:Mobile Safari AdBlock。 AFAIK,它也是Safari AdBlock桌面版的一个端口。我不知道很多细节,但我认为它需要安装一个破牢的iPhone。

总之,我认为没有任何可用于iPhone开发的交钥匙解决方案能够满足您的需求。除了创建自己的正则表达式引擎之外,最好的选择是查看TRE regex engine并尝试使用连接的正则表达式进行一些实验。但是,准备卷起你的袖子,因为你将不得不弄脏你的手,处理Cocoa的字符串,Unicode编码以及各种其他不愉快的东西 - {{{{{ 1}}在幕后照顾你。

答案 1 :(得分:0)

您是否正在将RegexKit.framework复制到iPhone应用的frameworks文件夹中?

答案 2 :(得分:0)

iPhone不支持嵌入式框架,因此即使它是为arm构建的,那里的指示也不会起作用。您只能使用静态链接的内容,因此您需要修改regexkit以构建为静态库,或者直接在项目中包含它的源代码。