可以找出哪个输入字符匹配正则表达式的哪一部分?

时间:2012-07-19 01:12:58

标签: regex computer-science regular-language computation-theory

我正在尝试构建一个使用正则表达式的工具来查找字符串中的模式(不是文本字符串,但现在这并不重要)。我熟悉自动机理论,即我知道如何实现基本的正则表达式匹配,如果字符串匹配我的正则表达式,则通过模拟教科书方式的自动机来输出true或false。

说我对a之前的所有b感兴趣,a之前没有b s,所以,这个正则表达式:{ {1}}。但我不只是想知道我的字符串是否包含这样的部分,我想得到a[^a]*b的输出,以便我可以检查它(记住,我实际上并没有处理文本)。

总结:假设我用括号标记a,如下所示:a并在输入字符串(a)[^a]*b上运行它,然后我希望第二个bcadacb为输出

或者,更一般地说,可以找出输入字符串中的哪些字符与正则表达式的哪个部分匹配?它是如何在文本编辑器中完成的?他们至少知道比赛开始的地方,因为他们可以突出比赛。我是否必须使用回溯方法,或者是否存在更智能,计算成本更低的方式?

编辑:可能没有必要使用适当的后向引用,即使用parens进行捕获并使用\ 1引用等。我知道后面的引用确实引入了回溯(或类似的东西)的需要,并使问题(IIRC)NP难。从本质上讲,我的问题是:捕获部分是否在没有反向引用的情况下,比正确的反向引用计算成本更低?

2 个答案:

答案 0 :(得分:4)

大多数文本编辑器通过使用回溯算法来完成此操作,在这种情况下,记录匹配位置是微不足道的。

通过使用括号位置信息扩充状态列表,也可以进行直接NFA模拟。这可以通过保持线性时间保证的方式完成。请参阅http://swtch.com/~rsc/regexp/regexp2.html#submatch

蒂莫斯的回答是正确的,但是你无法标记DFA状态,因为DFA状态对应于可能的NFA状态的集合,因此一个DFA状态可能代表通过paren的可能性(但也许是别的如果事实证明并非如此,那么将其记录为事实是不正确的。您确实需要处理NFA模拟。

答案 1 :(得分:1)

在为匹配构建DFA后,在正则表达式中的左括号后标记与第一个状态对应的所有状态。当您访问这样的状态时,保存当前输入字符的索引,当您访问对应于右括号的状态时,也保存索引。 当您达到接受状态时,输出两个索引。我不确定这是否是文本编辑器中使用的算法,但我就是这样做的。

相关问题