Python 从字符串的正则表达式列表中选择最紧密的匹配正则表达式的方法
我有一个字符串列表和一个正则表达式列表。我的目标是为每个字符串找到匹配的正则表达式。当然,有时列表中的多个正则表达式会与给定的字符串匹配。在这种情况下,我想用某种方法对它们进行排序 基本上,这将奖励静态部件匹配或更紧密的配合。例如,假设我的正则表达式是Python 从字符串的正则表达式列表中选择最紧密的匹配正则表达式的方法,python,regex,Python,Regex,我有一个字符串列表和一个正则表达式列表。我的目标是为每个字符串找到匹配的正则表达式。当然,有时列表中的多个正则表达式会与给定的字符串匹配。在这种情况下,我想用某种方法对它们进行排序 基本上,这将奖励静态部件匹配或更紧密的配合。例如,假设我的正则表达式是*:.*和开始:\d+,我的字符串是开始:18,那么显然我更相信第二个正则表达式是更好的匹配,因为它匹配静态内容,并预测最后的字符将是数字,而不仅仅是任何东西 我不确定我看到了整个算法的运行情况,也不确定我是否在描述一个真正的质量(更紧密的匹配),
*:.*
和开始:\d+
,我的字符串是开始:18
,那么显然我更相信第二个正则表达式是更好的匹配,因为它匹配静态内容,并预测最后的字符将是数字,而不仅仅是任何东西
我不确定我看到了整个算法的运行情况,也不确定我是否在描述一个真正的质量(更紧密的匹配),或者它是否会归结为某种启发式的“分数”,我必须分配给每个匹配
如果有什么不同的话,我正在使用python。我可以想出几种方法——这些只是“方向上的步骤” 首先,在Python中,您可以使用
debug
标志编译正则表达式,该标志为您提供有关如何解释正则表达式的信息
例如:
import re
p = re.compile('STARTING:\d+', re.DEBUG)
literal 83
literal 84
literal 65
literal 82
literal 84
literal 73
literal 78
literal 71
literal 58
max_repeat 1 65535
in
category category_digit
我想说,您匹配的文字数字越多,可以匹配的字符串就越少。类似地,当您在类别数字中有max\u repeat a b
后跟,您知道您可以在1到64k处有10个数字。如果您想计算所有可能匹配的字符串,那么这个数字将非常大。计算这个数字的对数更容易(也更合理)。对于调试输出中的每一行,您都可以找出该值
在这种情况下,它将是
0+0+0+0+0+0+0+0+0+(65535)*log(10)
相当多。但是如果你用另一个表达
p = re.compile('.*:.*', re.DEBUG)
你得到
max_repeat 0 65535
any None
literal 58
max_repeat 0 65535
any None
你的“熵”计算为log(255)*65536+0+log(255)*65536
超过4倍大
这将是一件很难实现的事情——特别是如果你开始添加look-around等,但是对于简单的表达式,它是可以做到的——并且它应该让你知道哪一个是“最好的”表达式
更好的做法是查看一个工具的输出,比如将其正则表达式引擎的内部工作转化为“可理解”的输出——您可以确切地看到它正在做什么/尝试什么,以及它最终如何找到匹配项。采用这种方法是很理想的,但这是非常困难的。我不太确定,但通过计算表达式,这种静态排序难道不可能吗?例如,对于您的示例,您已经知道,如果*:.*
和start:\d+
匹配,则第二个将比前一个更相关。我认为这必须是一种启发式,因为大多数正则表达式匹配无限多的字符串,并且比较无限并不总是容易的。作为一个起点,我建议将正则表达式分解为标记,并为每个标记分配一个分数:例如-1表示裸字符,10表示\d
,50表示
,100表示+
,200表示*
。尽管如此,这并不总是能给出很好的结果,例如,*-*
比裸*
的分数更高……您还可以根据精确度、正则表达式的长度或两者之间的平衡(通过评分)对它们进行排名。但是您需要一组好的测试字符串,以便测试正则表达式的灵活性。