语言 (a+)* 与 a* 相同吗?

问题描述

快速提问,如果 a 是正则表达式,那么 a* = (a+)* 是真的吗?

(a+)* 是一个有效的表达式吗?如果是,那么谁能解释为什么它与 a* 相同?很抱歉在这里提问,但我无法通过 Google 找到任何内容

解决方法

确实L(a*) = L((a+)*)。我们可以通过证明 L(a*)L((a+)*) 的子集来证明这一点,反之亦然。

要证明 L(a*)L((a+)*) 的子集,我们必须证明 a* 生成的任何内容也由 (a+)* 生成。我们只需要提供一种生成方法。正则表达式 a* 为所有整数 n 生成字符串 e = a^0,a = a^1,aa = a^2,...,a^k,...。要生成这些中的任何一个,只需从子表达式 a 中选择生成的子串 a+ 并替换,这会产生相同的表达式 a* 并且显然在相同的方式。

为了证明L((a+)*)L(a*)的子集,我们只需要指出表达式(a+)*中唯一的字母符号是a,因此表达式除了 a 的字符串之外,不能生成任何东西。由于 a* 生成所有此类字符串,因此同样清楚 L((a+)*) 是子集或 L(a*)

因为 L(a*)L((a+)*) 是彼此的子集,所以集合必须相等。也就是说,te 表达式生成相同的语言,因此是等价的。

,

是的,(a+)* 是有效的,等同于 a*。第一个表达式的意思是“至少一个 a 的序列,重复了 0 次或更多次”,第二个表达式的意思是“一个 a,重复了 0 次或更多次”。显然两者是等价的。

,

不,(a+)*a* 匹配相同的字符串,但由于 ReDoS,它是一种反模式。就其本身而言,(a+)* 是无害的,但如果您使用 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaab" 模式,许多正则表达式引擎可能会被 (a+)*x 字符串冻结。另一个不同之处在于您在 (a+)* 中有一个捕获组。