Regex (a*+;b*生成的字符串类型是什么

Regex (a*+;b*生成的字符串类型是什么,regex,compiler-construction,computation-theory,Regex,Compiler Construction,Computation Theory,除了像aa一样的任意数量的a和b的字符串。。或者bb,正则表达式(a*+b*)是否包含类似 ab 或者任何以b结尾的字符串 (a*+b*)和(a*b*)一样吗 我对正则表达式(a*+b*)生成的字符串有点困惑,如果有人能帮忙,我会非常感激。我认为在这里看正则表达式的正式定义很有帮助,也就是说,查找每个正则表达式e它生成了哪种语言L(e) 让我们从简单的开始: (一) regexp a(只有字母)怎么样?它的语言是 L(a) := {a}, 只有一个单词/字符“a” (二) 对于regexp

除了像aa一样的任意数量的a和b的字符串。。或者bb,正则表达式(a*+b*)是否包含类似

ab

或者任何以b结尾的字符串

(a*+b*)和(a*b*)一样吗


我对正则表达式(a*+b*)生成的字符串有点困惑,如果有人能帮忙,我会非常感激。

我认为在这里看正则表达式的正式定义很有帮助,也就是说,查找每个正则表达式e它生成了哪种语言L(e)

让我们从简单的开始:

(一) regexp a(只有字母)怎么样?它的语言是

 L(a) := {a},
只有一个单词/字符“a”

(二) 对于regexp e1+e2,其中e1和e2是regexp本身

L(e1 + e2) := L(e1) U L(e2).
L(e1 e2) := all words w such that 
we can write w = w_1w_2 with w_1 in L(e1) and w_2 in L(e2)".
例如,如果a和b是字符,L(a+b)={a,b}

(三) 对于regexp e1 e2(串联),其中e1和e2本身就是regexp

L(e1 + e2) := L(e1) U L(e2).
L(e1 e2) := all words w such that 
we can write w = w_1w_2 with w_1 in L(e1) and w_2 in L(e2)".
(四) 那么正则表达式*e**,其中e本身可能是正则表达式呢?直观地说,如果一个单词的形式是 w_1 w_2w_3w_4…w_n,每个i的L(e)中都有w_i。 所以

那么,L((a*+b*)呢

与(a*b*)类似:

首先,我认为它有助于“解构”正则表达式,正如我们前面所做的那样——因为正则表达式也可以被视为树,就像更为人所知的算术表达式一样,例如:

    +
  /   \
 *     *
 |     |
 a     b

除非您使用的是一种正则表达式语言,它将
*+
明确地分类为一种特殊的标记,这种标记要么具有特殊的含义,要么保留用于将来的扩展(并且现在生成定义的行为,或者语法错误),
a*+
的自然解析就是它的意思是
(a*)+
:后缀
+
应用于表达式
a*

如果这种解释适用,接下来我们可以观察到
(a*)+
只相当于
a*
。因此
a*+b*
a*b*
相同

首先,根据定义,
R+
意味着
RR*
。匹配一个
R
,然后匹配其中的零个或多个。因此,我们可以将
(a*)+
重写为
(a*)(a*)*

其次,
*
是幂等的,所以
(a*)*
就是
(a*)
。如果我们匹配“零次或多次
a
”,零次或多次,没有任何变化;净效应为零或更多
a
证明:
R*
表示这种无限扩展:
:不匹配,或匹配一个
R
,或匹配两个
R
。。。因此,
(a*)*
削弱了这种扩展:
(|a*| a*a*| a*a*|…)
。这些内部的
a*
-s依次表示单个的二级扩展:
(|(|(| a | aa | aaa |)|(| a | aa | |)|(| a | aaa |)|)
。通过分支
的关联性,我们可以将
(a |(b | c))
这样的结构展平为
(a | b | c)
,当我们对扩展进行此操作时,我们注意到有许多相同的术语,如空正则表达式
()
、单个
a
、双
aa
,等等。这些都简化为一个副本,因为
(| | | |)
相当于
()
(a | a | a |……)
相当于
(a)
,依此类推。也就是说,当我们通过增加长度对术语进行排序,并将多个相同的术语压缩为一个副本时,我们最终得到了
(|a | aa | aaa |…)
,这可以识别为just
a*
的扩展。因此
(a*)*
就是
a*


最后,
(a*)(a*)
只是指
a*
证明:与前面类似,我们扩展到分支:
(|a | aa | aaa |……)(|a | aa | aaa |……)
。接下来,我们注意到分支表达式的连接等价于项的笛卡尔乘积集。这就是说,
(a | b | c |…)(i | j | k |…)
的确切意思是:
(ai | aj | ik | bi | bj | bk | ci cj | ck |…)
。当我们将此产品应用于
(|a | aa | aaa |…)(|a | aa | aaa |…)
时,我们得到了大量的术语,当这些术语以增加的长度排列并进行重复数据消除时,会减少到
(|a | aa | aaa | aaa |…)
,这就是a*

对不起,我不认为a*+是一个有效的正则表达式,也不是计算理论中的语言表达式(对不起,我在大学里只上过一门关于这个主题的学位课)。如果你想要一个表示一个或多个“a”的词,后面跟一个或多个“b”,那么它应该是a+b+。如果只允许“a”不带“b”,只允许“b”不带“a”,甚至是空字符串,那么它将是ab。因此…
*+
是所有格贪婪量词。祝你玩得开心:谢谢你的阅读,对我来说是全新的。我使用正则表达式完全是基于FA的概念。@hek2mgl:你的解释可能是正确的,但我怀疑OP使用的是一本正式的语言教科书,
+
被用作数学中常见的析取运算符(“or”)。如果它是
a*
b*
,则等价的表达式是
a*.\b*
。如果这是唯一的表达式,则它将匹配所有
a
或所有
b
的子字符串,但不能同时匹配两者。如果它的
a*b*
与另一个具有相同影响,则可能会混合
a
,然后
b
。这个表达式
a*+b*
作为正则表达式使用了一个稍微复杂的运算符,
+
是量词的修饰符。在这种情况下,它告诉引擎的回溯部分在匹配后不要返回任何
a
。这是一个高级主题,可能不是你想要的。
    +
  /   \
 *     *
 |     |
 a     b