找到一个正则表达式来描述那些在字母表 {a,b} 上不包含两个连续 a 的单词

问题描述

我已尝试为该语言编写语法。这是我的语法:

S -> aS |乙| λ

我还想生成没有两个连续 a 的单词“bbababb”。 我开始, bS => bbS => bbaS => bbabS => bbabaS => bbababS => bbababbS => bbababbλ => bbababb。

最后我尝试了以下正则表达式, (a+b*)a*(a+b*)

非常感谢您的帮助。

解决方法

让我们试着写一些规则来描述所有没有两个连续 a 的字符串:

  1. 空字符串在语言中
  2. 如果 x 是语言中以 a 结尾的字符串,则可以在末尾添加 b 以获得该语言中的另一个字符串
  3. 如果 x 是语言中以 b 结尾的字符串,您可以在其中添加 a 或 b 以获得该语言中的另一个字符串

这让我们写下一个语法:

S -> e | aB | bS
B -> e | bS

那个语法应该对我们有用。考虑你的字符串 bbababb:

S -> bS -> bbS -> bbaB -> bbabS 
  -> bbabaB -> bbababS -> bbababbS
  -> bbababb

要将这样的正则文法转换为正则表达式,我们可以编写方程并求解 S:

S = e + aB + bS
B = e + bS

替换为 B:

S = e + a(e + bS) + bS
  = e + a + abS + bS
  = e + a + (ab + b)S

现在我们可以消除递归来求解 S:

S = (ab + b)*(e + a)

这给了我们一个正则表达式:(ab + b)*(e + a)

,

a 后面必须始终跟 b,最后一个字符除外,因此您可以将其表示为 "b or ab,带有可选的尾随 a":

\b(b|ab)+a?\b

live demo

\b(字边界)可能可以删除,具体取决于您的使用情况和正则表达式引擎。