Regex 如何使用字符范围实现正则表达式NFA?
当你读到这样的帖子时,一切看起来都很简单,直到你意识到在现实生活中,你不仅需要像“7”或“b”这样的直接字符,还需要:Regex 如何使用字符范围实现正则表达式NFA?,regex,dfa,nfa,Regex,Dfa,Nfa,当你读到这样的帖子时,一切看起来都很简单,直到你意识到在现实生活中,你不仅需要像“7”或“b”这样的直接字符,还需要: [A-Z] [^_] . 即字符类(或范围)。因此我的问题是——如何使用字符范围构建NFA?使用诸如“不是A”、“其他任何东西”之类的元字符,然后计算重叠范围?这将导致在使用最终自动机时使用树状结构,而不仅仅是一个表 更新:请假设字母表大小不小(>>256) 我问的是NFA,但后来我也想将NFA转换为DFA。最简单的方法是: 使用段作为NFA和DFA中过渡的标签。例如,范围[
[A-Z]
[^_]
.
即字符类(或范围)。因此我的问题是——如何使用字符范围构建NFA?使用诸如“不是A”、“其他任何东西”之类的元字符,然后计算重叠范围?这将导致在使用最终自动机时使用树状结构,而不仅仅是一个表
更新:请假设字母表大小不小(>>256)
我问的是NFA,但后来我也想将NFA转换为DFA。最简单的方法是:
[97122]
;单个字符“a”将变成[97,97]
;任何字符“.”都将变成[minCode,maxCode]
[minCode,96]
和[123,maxCode]
[a-c]| z
。因此,两次转变而不是四次 Procedure DISJOIN:
Input <- [97, 99] [97, 100] [98, 108]
Output -> [97, 97] [98, 99], [100, 100], [101, 108]
过程分离:
输入[97,97][98,99],[100100],[101108]
第2步。要从“设置状态”创建新的转换,应修改算法,如下所示:
for each symbol in DISJOIN(input symbols)
S <- empty set of symbols
T <- empty "set state"
for each state in "set state"
for each transition in state.transitions
I <- intersection(symbol, transition.label)
if (I is not empty)
{
Add I to the set S
Add transition.To to the T
}
for each segement from DISJOIN(S)
Create transition from "set state" to T
用于分离中的每个符号(输入符号)
请澄清“使用字符范围构建NFA”的意思@revo,使用
标记边缘,即如果输入为j
,则使用此标签,但如果输入为z
,则不使用此标签。这并不难,但是有几个重叠的标签(
,h
,
)会造成混乱。我不喜欢重新发明轮子,所以我在问。这一切都取决于你如何表现边缘。对于8位字符集,考虑256位的位图。如果设置了位n,则字符代码n在允许的范围内,例如。@tripleee,谢谢。我认为8位在实践中不会再流行了,Unicode更有可能。但这意味着每个标签8 KB(!)。这种方法是否用于任何公开的程序中,或者只是理论上的想法?如果您真的需要支持Unicode,那么还需要考虑一系列其他因素。请参阅关于regex支持的说明。同时,也许只考虑以一种合理的方式支持UTF-8。