【发布时间】:2015-12-09 01:41:48
【问题描述】:
我想知道正则表达式的优化技术
所以我试图从一个 400k 行的语料库中解析出每个钱的实例。我还需要包括诸如"$10,999.04" 和"one billion and six hundred twenty five thousand dollars" 之类的行以及介于两者之间的所有内容。这需要一个非常冗长的正则表达式,其中包含多个组实例,例如
MONEYEXPRESSION = '(?:\d\d?\d?(?:,?\d{3})*(?:\.\d+)?)'
(one|two|...|ninety[\s-]?nine|hundred|a hundred|MONEYEXPRESSION)((\s*and\s*|\s*-\s*|\s*)(one|two|...|ninety[\s-]?nine|hundred|a hundred|MONEYEXPRESSION))*
更重要的是,为了要求它是金钱的一个实例并避免匹配诸如"five hundred people were at the event" 之类的行,我有 4 个 OR'd 选项要求 "$", "dollars?", or "cents?" 至少在句子中的特定位置一次。
正则表达式差不多有 20k 个字符! :(
您可以想象,如果使用如此广泛的表达方式,以及任何不良做法,它确实会增加时间。过去 2 小时我一直在语料库上运行它,但仍然没有完成匹配。我想知道优化和修剪不必要的正则表达式的一些最佳实践是什么。我正在使用的操作很昂贵,可以补充更好的操作。如果可能有更好的方法来解决这个问题?
【问题讨论】:
-
也许您应该编写一个真正的解析器,而不是尝试对所有内容都使用正则表达式。
-
相信我,我想这样做,但这是我需要使用正则表达式的任务。这就是为什么我不是在寻求解决方案,而是寻求使其合理运行或最小化我已经编写的内容的技术
-
PCRE 支持递归,因此对于 100 以下的数字不必重复表达式,您可以定义一次,然后在
hundred和thousand之前引用它。 -
您是否预先编译一次正则表达式,然后使用编译后的版本?另外,您是否允许将其拆分为多个正则表达式模式,以便您可以先测试更频繁的部分并避免测试每一行的每个部分?
-
@ehaymore 我正在编译一次,我可以将其拆分为多个模式
标签: python regex parsing optimization