匹配正则表达式列表的算法

时间:2010-06-05 19:26:51

标签: c++ regex algorithm

我正在处理的项目有两个算法问题。我已经考虑过这些,并有一些怀疑,但我也很想听听社区的意见。

  1. 假设我有一个字符串和一个N个正则表达式列表(实际上它们是表示完整正则表达式功能子集的通配符模式)。我想知道字符串是否与列表中的至少一个正则表达式匹配。是否有一个数据结构可以允许我将字符串与次线性(可能是对数)时间内的正则表达式列表进行匹配?

  2. 这是上一个问题的扩展。假设我有相同的情况:一个字符串和一个N正则表达式列表,现在只有每个正则表达式与字符串中的匹配必须开始的偏移量配对(或者,如果您愿意,每个正则表达式)必须匹配从给定偏移量开始的给定字符串的子字符串。

  3. 举个例子,假设我有字符串:

    This is a test string

    和正则表达式模式和偏移:

    (a) his.*  at offset 0
    (b) his.*  at offset 1

    算法应该返回true。虽然正则表达式(a)与从偏移量0开始的字符串不匹配,但正则表达式(b)确实匹配从偏移量1开始的子字符串(“他是测试字符串”)。

    是否有数据结构可以让我在次线性时间内解决这个问题?

    一条可能有用的信息是,正则表达式列表中的许多偏移量通常是相同的(即通常我们在偏移X处多次匹配子字符串)。这可能有助于利用上述问题#1的解决方案。

    非常感谢您提出的任何建议!

3 个答案:

答案 0 :(得分:2)

我会假设你真的具有正则表达式的力量。

  1. 要确定某个字符串是否与某个表达式e_1, e_2, ..., e_n匹配,只需匹配表达式e_1 + e_2 + ... + e_n(有时+运算符会写为| )。

  2. 给定表达式偏移对(e_1, o_1), ..., (e_n, o_n)和字符串,您可以检查是否i使得字符串在偏移量{{1}处与表达式e_i匹配通过匹配表达式o_i

  3. 根据各个表达式的形式,您可以获得次线性表现(尽管不是这样)。

答案 1 :(得分:1)

如果表达式足够简单(通配符模式),并且您的表达式集是预先确定的,即只有要匹配的输入发生变化,那么您可以构造一个匹配表达式并集的finite state machine,即,表达“(r1)|(r2)| ......”。

构造该机器需要时间和空间至少 O(N)(但我想这不是指数,这是正则表达式的最坏情况)。然后匹配为O(长度(输入)),与N无关。

OTOH,如果你的表达式是程序输入的一部分,那么就没有次线性算法,只是因为必须考虑每个表达式。

答案 2 :(得分:0)

(1)将所有正则表达式组合成一个大联盟:(r1)|(r2)|(r3)|...

(2)对于每个带有偏移 n 的正则表达式,将 n 点添加到开头加一个锚点。因此,偏移6处的his.*变为^......his.*。或者,如果您的正则表达式语法支持它,^.{6}his.*