问题描述
快速提问,如果 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+)*
中有一个捕获组。