RegExp特性是如何作为NFA实现的?

RegExp特性是如何作为NFA实现的?,regex,Regex,我了解简单的正则表达式功能是如何在诸如*、|和()等应用程序中实现的 我想知道如何实现更复杂的功能,如^,$,[],[-],等等。它们看起来很简单,但我想知道这些表达式是如何转换成NFA的 以这个regexp为例:^k[a-z0-9]{9}$。如何将其转换为NFA?好的,让我们使用相同的表达式: ^k[a-z0-9]{9}$ 设置 NFA中用于表示regexp的每个转换通常表示为一个集合,而不是单个字符 因此,“k”字符的转换表示为包含单个字符的集合,而“[a-z0-9]”表示为包含这些字符的集

我了解简单的正则表达式功能是如何在诸如
*
|
()
等应用程序中实现的

我想知道如何实现更复杂的功能,如
^
$
[]
[-]
,等等。它们看起来很简单,但我想知道这些表达式是如何转换成NFA的


以这个regexp为例:
^k[a-z0-9]{9}$
。如何将其转换为NFA?

好的,让我们使用相同的表达式:

^k[a-z0-9]{9}$

设置
NFA
中用于表示regexp的每个转换通常表示为一个集合,而不是单个字符

因此,“k”字符的转换表示为包含单个字符的集合,而“[a-z0-9]”表示为包含这些字符的集合

regexpr
NFA
的特定实现可能会为单个字符提供一个替代的、传统的、简化的转换,但这可能会被描述为一个优化细节

锚定 请注意,在具有显式锚定字符的正则表达式中

k[a-z0-9]{9}

相当于

(.[a-z0-9]{9}(.)

因为事实就是这样。当正则表达式被锚定时,NFA实际上就是它的本来面目。换句话说,NFA总是锚定到搜索空间的开头和结尾,如果不存在锚定字符,(*)会在后台自动地在正则表达式的开头或结尾打上一记耳光

重复 表达式{N}

这通常是通过简单地在内部复制正则表达式N次来完成的。明确地扩展它


以上是正则表达式NFA的典型实现。

我想您可能想看看。

缩写NFA代表什么?还可以看看格式良好的公式和(扩展的)Backus Naur形式,尽管我还没有看到格式良好的公式是什么的明确定义@user2740741我认为如果我们通过添加诸如$,^之类的文字特殊字符来预处理输入字符串,那么正则表达式引擎将能够从字面上匹配这些特殊字符,$right?正则表达式被解析为NFA状态机的外部表示形式。在这种情况下,“预处理”毫无意义。如果输入字符串没有锚点,“*”转换是NFA内部表示中的第一个/最后一个转换。如果它确实具有锚定,则不会添加相应的过渡。此时,NFA的内部表示与输入字符串几乎没有相似之处。您的非锚定表达式宁愿转换为
*k[a-z0-9]{9}
k
很重要,因为它必须匹配,不需要匹配任何其他字符,其中可能没有任何字符,最后,可能有一个0或多个前置字符。@SamVarshavchik,如果您能给出一些简单的示例,我们将不胜感激。谢谢,我从来没有听说过这种算法,看到一个正则表达式作为NFA很好地说明了回溯(尽管给出的示例没有)。你提出汤普森算法是因为它的简单还是有其他原因?不,唯一的原因是汤普森算法是我唯一听说过的:)看起来不同的是,由此产生的NFA将没有与Glushkov的ε-跃迁…这篇论文可能对OP BTW感兴趣