从正则表达式中提取静态字符串

时间:2012-12-20 21:43:18

标签: regex

我正在尝试有效地提取静态字符串(必须匹配给定正则表达式匹配的字符串)。我已经能够在最简单的情况下做到这一点,但我正在努力发现一个更强大的解决方案。


给出正则表达式,例如下面的正则表达式

"fox jump(ed|ing|s)"

会给我们

"fox,jumped,jumping,jumps"

另一个例子是

"fox jump(ed|ing|s)?"

会给我们

"fox,jump"

因为可选的运算符


我现在的算法过于简单了。它将从正则表达式的末尾开始并删除组或单个字符,然后是这些运算符“*?”以及“爆炸”分组OR运算符“(|)”。这种方法效果很好,但没有考虑正则表达式的完整语法。您可以将其视为正则表达式的最小集合生成过程(正则表达式可以“生成/必须匹配”的最小字符串集合)。

WHY吗 的 我试图将一堆文本与一大堆正则表达式进行匹配。如果我可以获得“必需”这些正则表达式的“关键字”列表,我可以对该关键字进行快速文本搜索,以过滤我关心的正则表达式(忽略我保证不匹配的正则表达式,甚至跳过该文本完全有效地没有在文本上运行任何正则表达式,因为我们保证在我们的正则表达集中没有匹配)。我可以在一个有效的数据结构(Binary Search / Trie / Aho-Corasick)中组织这组关键字,以便在我尝试通过有限自动机运行文本之前过滤一组正则表达式。在尝试运行正则表达式之前,我可以将极快的字符串匹配算法作为过滤阶段运行。在这个简单的过程中,我已经能够提高吞吐量。

2 个答案:

答案 0 :(得分:0)

如果我正确理解你的问题,你正在寻找一组单词,这样所有这些单词都是(给定的)正则表达式接受的任何单词的(不相交的)子串。

我的猜测是这样的一组通常是空的,但是可以找到它。

为了找到这样的集合,我提出了以下算法:

  1. 找到与输入正则表达式对应的FA。
  2. 识别起始状态S和接受状态F之间的桥(https://en.wikipedia.org/wiki/Bridge_(graph_theory))。例如,可以通过移除边E并询问FA中是否存在从S到E的路径来完成。删除 - 对所有边缘重复此操作。
  3. 在接受运行期间必须击中作为桥的所有边,并且每条边对应于输入字母。
  4. 您现在可以通过端到端连接后续桥接边缘来生成所需的单词。
  5. 我认为从算法结构可以看出FA(而不是DFA)足以使其工作。再一次,证明会很好,但我认为它应该有效:)

答案 1 :(得分:0)

查看库Xeger,它给出了一个正则表达式,它将为您提供所有匹配的字符串。

您似乎只想保留这些字符串的公共前缀(您说要忽略可选运算符的部分),但如果您这样做,您可能会捕获具有该公共前缀但没有您想要的结尾的叮咬(例如"跳跃"在你的例子中)。如果这不是问题,那么只需找到Xeger给出的最短字符串,假设可选运算符仅出现在正则表达式的末尾。