对于我的应用程序,我需要查看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我跟着文档中的内容)
所以我的问题是:
如果字符串被1000个正则表达式中的任何一个匹配,您知道检查字符串的任何更快的方法吗?
或者你知道如何在iPhone或任何其他正则表达框架上使用"普通"RegexKit,这将在一秒钟内完成我需要的工作吗?
提前致谢
注意:我是RegexKit等人的作者.
这是一个相当复杂的答案.. :)
首先,将一千个正则表达式与任何常用的正则表达式引擎实现相匹配将会相当慢,除了TCL和TRE正则表达式引擎.之所以RegexKit.framework
大大优于RegexKitLite
此任务的原因,是为这项任务RegexKit.framework
提供了相当多的非平凡,优化的代码.这是因为它在Safari AdBlock中使用,它需要针对URL执行正则表达式的批量匹配.它根据成功匹配的次数,按照排序顺序保留正则表达式列表.这是基于以下观察:Safari AdBlock中使用的一些正则表达式模式比其他模式更频繁地匹配,并且首先尝试这些模式会显着减少需要尝试的正则表达式的数量,以确定是否存在"命中".还有一个小的负面命中缓存,以及许多多线程代码来并行执行匹配.这些都不会进入Lite
版本,因为它绝对不是一个轻量级的功能 - 可能只有60-70KB的代码才能实现这一功能,更不用说保留一千个编译的正则表达式的巨大内存占用周围.
使用RegexKitLite
这种模式匹配必然非常非常慢.第一个问题是它只保留了最近使用过的编译正则表达式的小缓存.默认情况下,缓存设置为just 23
,因此抛出一千个正则表达式会导致每次使用时都编译每个正则表达式.
正如其他人所指出的那样,RegexKit.framework
并没有真正设置在iPhone上使用.即使你身边的"链接到外部框架"规定了,默认的编译RegexKit.framework
不包括arm
在其脂肪二元结构(它包括ppc
,ppc64
,i386
,和x86_64
).您真正需要做的是设置一个新的构建目标,以创建一个静态库.真的,不是很难做到.
我担心如果这种模式匹配是你需要做的事情,你可能不得不推出自己的正则表达式引擎.你需要的是一个正则表达式引擎,可以将你的千个正则表达式连接在一起,例如" r1|r2|r3|r4
".最正则表达式引擎,特别是pcre
与ICU
(由所使用的那些RegexKit.framework
和RegexKitLite
,分别地),以几乎从左到右的方式评估这样的正则表达式.我们需要的是几乎类似于DFA的引擎,它可以同时评估所有可能的状态.有关更多信息,请参阅此链接.我已经构建了一个这样的正则表达式引擎,甚至可以处理后引用(比大家说的要容易得多)〜O(M*log2(N))
(M是要匹配的文本的大小,N是正则表达式的大小)时间,但它是没做完.如果是这样的话,它会像等离子火炬一样通过黄油来解决这类问题.
我知道至少有一个人移植RegexKit.framework
到iPhone上:Mobile Safari AdBlock.AFAIK,它也是Safari AdBlock桌面版的一个端口.我不知道很多细节,但我认为它需要安装一个破牢的iPhone.
总而言之,我认为iPhone开发没有任何交钥匙解决方案能够满足您的需求.除了创建自己的正则表达式引擎之外,最好的选择是查看TRE正则表达式引擎并尝试使用连接的正则表达式进行一些实验.但是,准备好卷起你的袖子,因为你将不得不弄脏你的手并处理Cocoa的字符串,Unicode编码以及各种其他不愉快的东西 - 这些RegexKitLite
需要注意的东西在幕后为你服务.