算法:正则表达式字符交集

时间:2016-05-04 09:50:02

标签: java regex algorithm

我在Java中有两个正则表达式,我想知道第一个正则表达式匹配的字符串的最后一个字符(成功)是否与第二个匹配的字符串的第一个字符(成功)匹配

这些表达式很复杂,不仅限于字符限制,还限制了长度或形式。

我正在调查https://code.google.com/archive/p/xeger/,但这只是一半。

(我正在解决一个问题,即在这些正则表达式限制的两个连续字符串之间是否需要分隔符,或者解析器是否能够在没有分隔符的情况下将它们分开)

示例:

Regex1 = <
Regex2 = [:a-zA-Z]([:a-zA-Z]|-|_|\.|[0-9])*
Regex3 = Regex2

[Regex1] [Regex2]不需要分隔符,因为解析器会将字符串<xml安全地解析为2个令牌(<xml)。

[Regex2] [Regex3]分享了很多字符,解析器有几种可能性来解析如何解析字符串table

我知道正则表达式评估背后的理论(自动...),但是我想避免自己实现DFA生成。

2 个答案:

答案 0 :(得分:1)

我在github上有一个可以为你构建DFA的开源库:http://mtimmerm.github.io/dfalex/

请注意,您的问题似乎不正确。如果您想知道匹配两个正则表达式的字符串之间是否需要分隔符,您可能需要知道任何可以“扩展”第一个正则表达式的成功匹配的字符是否也可以启动第二个正则表达式的匹配。在DFA中,可以扩展匹配的字符是接收状态之外的转换字符。

我应该补充一点,你不一定需要建立DFA来回答这些问题。第一个+最后一个字符,扩展字符以及它是否与空字符串匹配,是可以通过对正则表达式AST进行简单递归操作来回答的问题。

例如(对布尔和集合操作使用|和&amp;):

如果正则表达式匹配空字符串,则NULLABLE(X)为真。然后:

NULLABLE(AB) = NULLABLE(A) & NULLABLE(B)
NULLABLE(A|B) = NULLABLE(A) | NULLABLE(B)
NULLABLE(A+) = NULLABLE(A)
NULLABLE(A?) = true

FIRST(X)成为可以启动正则表达式的字符集:

FIRST(AB) = NULLABLE(A) ? FIRST(A)|FIRST(B) : FIRST(A)
FIRST(A|B) = FIRST(A)|FIRST(B)
FIRST(A+) = FIRST(A?) = FIRST(A)

EXT(X)成为可以扩展正则表达式的字符集:

EXT(AB) = NULLABLE(B) ? EXT(A)|EXT(B) : EXT(B)
EXT(A|B) = EXT(A) | EXT(B)
EXT(A+) = EXT(A?) = EXT(A)|FIRST(A)

答案 1 :(得分:0)

而是一个抽象的答案,但也许你可以把它变成代码:

正则表达式总是可以变成NFA(Thompson),因此变成DFA(子集构造)。 See this interactive website for examples。这个特殊问题可能更容易在DFA中分析:

当且仅当在第一个DFA中有一个边缘导致最终状态标记有一个字符时,在第二个DFA中有一个初始状态的外边缘,那么你的条件满足。

请参阅此示例,了解表达式aa+b*ba+。以蓝色圈出的边是在第一个表达式中到达最终状态的边,因此最终字符可以是ab。以红色圈出的边是第二个DFA中的传出边,因此第一个字符只能是b。在这种情况下,可能会有重叠。

First DFA Second DFA