Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从字符串的正则表达式列表中选择最紧密的匹配正则表达式的方法_Python_Regex - Fatal编程技术网

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表示
*
。尽管如此,这并不总是能给出很好的结果,例如,
*-*
比裸
*
的分数更高……您还可以根据精确度、正则表达式的长度或两者之间的平衡(通过评分)对它们进行排名。但是您需要一组好的测试字符串,以便测试正则表达式的灵活性。