Swift 3:使用许多正则表达式检查许多字符串的最高效方法

时间:2017-09-01 06:07:33

标签: ios regex swift nsregularexpression

我有一个包含数百个字符串的列表和一个包含10k正则表达式的数组。

我现在必须迭代所有字符串并检查哪些10k正则表达式匹配。什么是最有效的方法?

目前我正在这样做:

myRegularExpression.firstMatch(in: myString, options: myMatchingOption, range: NSMakeRange(0, myString.characters.count)) == nil

其中myRegularExpressionNSRegularExpression存储以供重复使用,myMatchingOptionNSRegularExpression.MatchingOptions(rawValue: 0)

是否有更快,更高效的方法来检查字符串是否与这些10k正则表达式中的一个匹配?

编辑:

我不仅要知道我的10k正则表达式中的一个是否合适,还要知道哪一个。所以目前我在for循环中有一个for循环:外部循环遍历我的几百个字符串,对于每个字符串我迭代我的10k规则,看看是否适合一个规则(当然如果一个规则适合我可以停止对于那个字符串,大致如此:

for string in stringsToCheck {
    for rule in myRules {
        if string.matches(rule) {
            // continue with next string of stringsToCheck
        }
    }
}

1 个答案:

答案 0 :(得分:0)

根据您正在运行此平台的平台,使用多个线程分离工作可能会提供一些响应时间改进,但我相信对此进行真正戏剧性的优化需要对正则表达式的性质有所了解。

例如,如果表达式没有特定的优先顺序,您可以重新排列(重新排序)它们以使最有可能的"匹配"在列表中排在第一位。这可以通过表达式的提供者或使用某种函数来预先评估它们的复杂性(例如表达的长度,可选或组合符号的存在)。 或者可以通过收集(和持久)每个表达式的命中/未命中计数来统计评估它。但是,当然这样的优化假设每个字符串将匹配至少一个表达式并且80/20规则适用(即20%的表达式匹配80%的字符串)。

如果表达式非常简单并且只使用字母图案,那么使用更多"手册"可以获得更好的性能。匹配函数的实现(而不是正则表达式)。在最好的情况下,简单的字母模式可以转换为字符树,并在性能改进方面产生数量级。

请注意,这些解决方案并不相互排斥。例如,如果大部分表达式是简单模式而只有少数模式具有复杂模式,那么您不必使用洗澡水丢弃婴儿:您可以将简单模式优化应用于其中一部分规则和使用"蛮力"嵌套循环到剩下的复杂的。

过去我遇到过类似的问题,需要在数十万条记录中应用数千条规则来处理保险索赔。传统的专家系统"方法是创建一个规则列表并通过它运行每个记录。显然,这需要花费大量的时间(比如2个月的执行时间来处理一个月的索赔)。用低于" purist"来看待它。心态,我能够说服我的客户,应该按层次定义规则。因此,我们将它们分成一组资格规则和一套决策规则。然后,我们通过创建资格组和决策组来进一步完善结构。我们最终得到的是一个粗糙的树结构,其中规则允许系统缩小应该应用于给定记录的规则的数量。有了这个,250,000条记录的6周处理时间缩短为7小时(这是1988年的记忆)。

所有这一切都表明,退回到要解决的问题的本质可能会提供一些优化机会,当仅仅考虑一个流程选项的机制时,这些机会是不可见的。