根据歧义性对“正则表达式”进行评分

时间:2018-07-17 17:38:06

标签: regex algorithm

我有许多由用户提供的正则表达式,并选择其中一个与输入字符串匹配的正则表达式。现在,如果有多个表达式匹配,我想选择最具体的表达式,即最不明确的表达式。

更具体地说:我正在用几个人用Python编写一个IRC机器人。可以通过正则表达式注册命令,其中某些命令会重叠。可以为每个命令提供某种优先级,但是这会引入另一个故障点。我希望基于提供的正则表达式的歧义性,是否可以在命令注册时自动生成某种“分数”。我还无法在Google上找到合适的算法。

一种天真的方法可能会满足我现在的需要,它可能是正则表达式中字符与通配符的比率,但是,如果您了解此处的任何具体算法,我将很感兴趣。

1 个答案:

答案 0 :(得分:2)

如果使用可以转换为DFA的grep样式正则表达式,则对于任何正则表达式,都可以计算出随机字符串与之匹配的概率。

对于您要寻找的分数类型,我认为这是一个合理的选择-随机字符串匹配的可能性越低,则正则表达式越具体。为了加分,您对“随机字符串”的概念可以模拟人们实际键入的各种字符串。

这并不容易,但是可行。该过程将如下所示:

  1. 为正则表达式生成最小DFA(https://en.wikipedia.org/wiki/Deterministic_finite_automaton)。通常,这是通过使用Thompson的构造(https://en.wikipedia.org/wiki/Thompson%27s_construction)创建NFA,使用powerset构造(https://en.wikipedia.org/wiki/Powerset_construction)转换为DFA,然后应用Hopcroft的算法或类似的方法(https://en.wikipedia.org/wiki/DFA_minimization)来完成的创建最小的DFA。
  2. 向DFA添加一个接受状态以处理“字符串结尾”。在“字符串结尾”上添加从先前的每个接受状态到新的单个接受状态的过渡。
  3. 现在,您需要计算随机字符串进入每种状态的概率。对于开始状态,此概率为1。对于其他状态,您可以创建一个方程式来计算将要输入的概率。它是进入每个先前状态的概率的总和乘以从该状态到目标状态的下一个转换的(恒定)概率。您可以根据每个字母在键入命令中实际出现的频率来加权转换概率。您可能会假设字符串在每种状态(无论是否过渡到接受状态)结束的概率都是恒定的
  4. 在步骤(3)中,您不能直接计算概率,但是可以为N个未知数建立N个线性方程,其中,未知数是除开始状态外的所有状态的输入概率的状态。使用高斯消除(https://en.wikipedia.org/wiki/Gaussian_elimination)或其他标准方法来求解线性方程组,以计算每个状态由随机字符串输入的概率。

步骤(4)将为随机字符串进入接受状态分配概率,这是随机字符串与正则表达式匹配的概率。此概率越低,则正则表达式越具体。