我最近一直在尝试一些正则表达式。现在,我有3个符号a,b和c。
我首先看了一个我不想要连续2次的情况。正则表达式将是这样的:
((b|c + a(b|c))*(a + epsilon)
现在我想知道是否有办法将这个问题概括为:
正则表达式,没有两个连续的a,没有两个连续的b。我试过像:
这样的东西(a(b|c) + b(a|c) + c)* (a + b + epsilon)
但这接受了诸如“abba”或“baab”之类的输入,这些输入将有2个连续的a(或b),这不是我想要的。有谁能建议我出路?
答案 0 :(得分:3)
如果您无法进行否定匹配,那么您可以使用否定前瞻来排除与aa
和bb
匹配的字符串?类似于以下内容(有关详细信息,请参阅Regex 101):
(?!.*(aa|bb).*)^.*$
答案 1 :(得分:2)
我(我想)通过手工绘制有限状态机来解决这个问题,然后使用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
如果你看一下过渡,你会发现它相当简单 - 我的状态对应于字母表中每个字母的“接收器”,我只允许从该状态转换到其他字母(不是“沉”字母)。例如,s1
是a
的“接收器”。在所有其他州,您可以使用s1
到达a
。但是,当您进入s1
时,您只能使用b
或c
来摆脱它,它们有自己的“接收器”s2
和{{ 1}}分别。由于我们可以重复s3
,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
作为选择运算符(通常我们的编码器称为+
),这意味着它可能不适合粘贴到代码中。但是,我太害怕改变它并冒着破坏我的正则表达的风险:)
答案 2 :(得分:0)
您可以使用反向引用来匹配prev char
string input = "acbbaacbba";
string pattern = @"([ab])\1";
var matchList = Regex.Matches(input, pattern);
此模式将匹配:bb,aa和bb。如果您的输入模式中没有任何匹配,则表示它不包含重复的a或b。
说明:
([ab]):定义一个组,你可以在这里扩展你的符号
\ 1:返回引用该组,例如,当' a'匹配,\ 1将是' a'