具体来说,我注意到正则表达式本身的语言并不规律。所以,我不能使用正则表达式来解析给定的正则表达式。我需要使用解析器,因为正则表达式本身的语言是无上下文的。
有没有什么方法可以用可以使用正则表达式解析结果字符串的方式表示正则表达式?
注意:我的问题不是关于是否存在与正则表达式的当前语法匹配的正则表达式,而是正如我们今天所知的那样是否存在正则表达式的“表示”(可能不像我们所知道的那样整齐)可以使用正则表达式解析。另外,请有人删除dup,因为它不是dup。我问的是完全不同的东西。我已经知道正则表达式的当前语言不规则(这是我开始原始问题的方式)。
答案 0 :(得分:1)
答案可能是否定的。
正如您所指出的,所有可能的正则表达式本身的集合不是常规集合。任何 TRUE 正则表达式(不是那些扩展的)都可以转换为有限自动机(FA)。如果正则表达式可以用可以自己解析的形式表示,那么FA也可以通过正则表达式进行解析。
但就我所知,这是不可能的。 RE本身可以简化为三种基本操作(根据龙书):
ab
a|b
a*
kleen闭包可以匹配无数个字符,但它不能知道要匹配多少个字符。
想想这样的情况:你想连续3个a
匹配。然后相应的正则表达式为/aaa/
。但是如果你想要比赛4,5,6 ... a
s怎么办?只有一个RE的解析器无法知道a
的确切数量。因此它无法为任意表达式提供正确的匹配。但是,RE解析器必须匹配无限不同形式的RE。根据你的表达,正则表达式无法匹配所有可能性。
嗯,RE解析器的唯一区别是它不需要一个tokenizer。(可能这就是RE用于词法分析的原因)RE中的每个字符都是一个标记(不包括那些转义字符)。但是要解析RE,无论它是什么转换,都必须面对NFA / DFA / TREE ...所有等效结构都不能由RE本身解析。
答案 1 :(得分:0)
根据“代表”的意思,答案是“是”或“否”:
如果您想要一种语言(同形)将1:1映射到通常的基本正则表达式语言,答案是否定的,因为正则语言不能与非正则语言同构,而标准正则表达式语言是非常规的。
如果“代表”仅表示指定常规语言的另一种方法,那么答案是肯定的,现在我可以想到至少三种实现此目的的方法:
“最愚蠢”和最简单的方法是定义一些从自然数到所有有效标准正则表达式集合的射影映射f : ℕ -> RegEx
。您可以使用正则表达式0|1[01]*
定义自然数,并且以自然数n
(表示自然数)的字符串表示的正则语言是f(n)
表示的正则语言。
当然,自然数字所附带的含义对人类读者来说根本不是显而易见的,因此这种“正则表达式语言”将完全无用。
由于括号是简单正则表达式中唯一的非正则部分,因此,人类最容易理解的方法是扩展标准简单正则表达式语法,以允许悬挂括号并为悬挂括号定义语义。
显而易见的选择是忽略不匹配的右括号,并将不匹配的右括号解释为与正则表达式的开头匹配。从本质上讲,这相当于根据需要在正则表达式的开头隐式插入了多个括号,并在结尾处隐式插入了多个括号。另外,(*
必须被解释为空字符串的重复。如果我什么都没错过,则此定义应将任何字符串转换为具有指定含义的“正则表达式”,因此.*
定义此“正则表达式语言”。
此变体甚至具有与标准正则表达式相同的抽象语法。
另一个变体是指定使用常规语言直接识别该语言的NFA,例如:([a-z]+,([^,]|\\,|\\\\)+,[a-z]+\$?;)*
。
这个想法是将[a-z]+
用作状态标签,并且该表达式是从源状态(s, c, t)
到目标状态s
的过渡三元组t
的列表消费字符c
和一个$
表示接受转换(请参见下面的注释)。在c
中,反斜杠用于转义逗号或反斜杠-我假设您对标准正则表达式使用了相同的字母,但是您当然可以将中间部分替换为表示符号的任何其他正则语言符号你希望。
提到的第一个源状态是(单个)初始状态。空表达式定义空语言。
上面,我写的是“接受过渡”,而不是“接受状态”,因为用纯常规语言很难表示出来。您可以将包含$
的三元组解释为两个过渡,即一个从c
到新的唯一状态的过渡消耗了s
,而从该状态到{{1 }}。通过使用t
三元组替换每个进入接受状态的过渡,并使用非$
三元组替换每个进入不接受状态的过渡,这应该可以表示任何NFA。
一个可能使“是”部分看起来更直观的注释:汇编语言是常规的,甚至是图灵完整的,因此,如果不可能使用a来指定“纯”常规语言,那将是意外的。普通语言。