【发布时间】:2021-06-10 18:50:09
【问题描述】:
快速提问,如果 a 是正则表达式,那么 a* = (a+)* 是真的吗?
(a+)* 是一个有效的表达式吗?如果是,那么任何人都可以解释为什么它与 a* 相同?很抱歉在这里提问,但我无法通过 Google 找到任何内容。
【问题讨论】:
标签: algorithm regular-language
快速提问,如果 a 是正则表达式,那么 a* = (a+)* 是真的吗?
(a+)* 是一个有效的表达式吗?如果是,那么任何人都可以解释为什么它与 a* 相同?很抱歉在这里提问,但我无法通过 Google 找到任何内容。
【问题讨论】:
标签: algorithm regular-language
是的,(a+)* 有效且等效于 a*。第一个表达式表示“至少一个a的序列,重复0次或多次”,第二个表示“一个a,重复0次或多次”。显然两者是等价的。
【讨论】:
不,(a+)* 与 a* 匹配相同的字符串,但它是反模式,因为 ReDoS。 (a+)* 本身没有害处,但如果您使用 (a+)*x 模式,许多正则表达式引擎可以用 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaab" 字符串冻结。另一个区别是您在 (a+)* 中有一个捕获组。
【讨论】:
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*,并且显然会以相同的方式生成相同的a 字符串。
为了证明L((a+)*) 是L(a*) 的子集,我们只需要指出表达式(a+)* 中唯一的字母符号是a,因此该表达式除了a 字符串之外不能生成任何内容。因为a* 会生成所有此类字符串,所以同样清楚L((a+)*) 是一个子集或L(a*)。
因为L(a*) 和L((a+)*) 是彼此的子集,所以集合必须相等。也就是说,te 表达式生成相同的语言,因此是等价的。
【讨论】: