没有连续 2 个 a 和 b 的正则表达式

Regex with no 2 consecutive a's and b's

我最近一直在尝试一些正则表达式。现在,我有 3 个符号 a、b 和 c。

我先看了一个不想连续2个a的案例。正则表达式类似于:

((b|c + a(b|c))*(a + epsilon)

现在我想知道是否有一种方法可以概括这个问题,比如:

没有两个连续的 a 和两个连续的 b 的正则表达式。我试过类似的东西:

(a(b|c) + b(a|c) + c)* (a + b + epsilon)

但是它接受诸如 "abba" 或 "baab" 之类的输入,它们将有 2 个连续的 a(或 b),这不是我想要的。任何人都可以建议我出路吗?

如果您不能进行否定匹配,那么也许您可以使用否定前瞻来排除匹配 aabb 的字符串?类似于以下内容(有关详细信息,请参阅 Regex 101):

(?!.*(aa|bb).*)^.*$

我(认为我)通过手绘一个有限状态机解决了这个问题,然后使用 FSM2Regex 生成一个正则表达式。状态机写在下面(使用网站的语法):

#states
s0
s1
s2
s3
#initial
s0
#accepting
s1
s2
s3
#alphabet
a
b
c
#transitions
s0:a>s1
s0:b>s2
s0:c>s3
s1:b>s2
s1:c>s3
s2:a>s1
s2:c>s3
s3:c>s3
s3:a>s1
s3:b>s2

如果你看一下转换,你会发现它相当简单——我有对应于字母表中每个字母的 "sink" 的状态,我只允许从该状态转换出其他字母字母(不是 "sink" 字母)。例如,s1a 的 "sink"。从所有其他州,您可以使用 a 到达 s1。但是,一旦进入 s1,您只能使用 bc 退出它,它们有自己的 "sinks" s2s3 分别。因为我们可以重复 c,所以 s3 在字符 c 上有一个到自身的过渡。将块文本粘贴到站点中,它会为您绘制所有内容,并生成正则表达式。

它为我生成的正则表达式是:

c+cc*(c+$+b+a)+(b+cc*b)(cc*b)*(c+cc*(c+$+b+a)+$+a)+(a+cc*a+(b+cc*b)(cc*b)*(a+cc*a))(cc*a+(b+cc*b)(cc*b)*(a+cc*a))*(c+cc*(c+$+b+a)+(b+cc*b)(cc*b)*(c+cc*(c+$+b+a)+$+a)+b+$)+b+a

我敢肯定,这不是最优的 :)

编辑:生成的正则表达式使用 + 作为选择运算符(我们编码人员通常称为 |),这意味着它可能不适合粘贴到代码中。但是,我太害怕更改它并冒着破坏我的正则表达式的风险:)

您可以使用反向引用来匹配前一个字符

string input = "acbbaacbba";
string pattern = @"([ab])";
var matchList = Regex.Matches(input, pattern);

此模式将匹配:bb、aa 和 bb。如果您的输入模式中没有任何匹配项,则意味着它不包含重复的 a 或 b。

解释:

([ab]): 定义一个组,你可以在这里扩展你的符号

\1:反向引用组,例如,当匹配 'a' 时,\1 将是 'a'

查看此页面:http://www.regular-expressions.info/backref.html