You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何构建{a,b}语言中匹配奇数个a和奇数个b的正则表达式?

嘿,我来帮你搞定这个正则问题!

首先,先说说你的正则为什么会匹配空串:你的表达式是(((aa+bb)*(ab+ba))*+((ab+ba)(aa+bb)*)*),这里最外层的两个分支都用了*——((aa+bb)*(ab+ba))*允许匹配0次,((ab+ba)(aa+bb)*)*也允许匹配0次。当两个分支都匹配0次时,整个正则就会匹配空串,这就是评分器报错的原因。

接下来,咱们来构造正确的正则,目标是匹配{a,b}语言中包含奇数个a和奇数个b的字符串。

核心思路

要满足奇数个a和奇数个b,我们可以从状态机的角度思考:

  • 初始状态:偶数个a、偶数个b(空串就在这里,必须排除)
  • 我们需要最终到达的状态:奇数个a、奇数个b
  • 任何aabb的组合不会改变a/b的奇偶性(因为加了偶数个相同字符)
  • 任何abba的组合会同时改变a和b的奇偶性(各加1个,奇偶翻转)

所以,正确的字符串必须包含奇数次abba(每次翻转奇偶性,奇数次翻转后从初始的偶偶变成奇奇),同时可以在任意位置插入任意数量的aabb

正确的正则表达式

基于这个思路,最终的正则可以写成:

^(?:(?:aa|bb)*(?:ab|ba))(?:(?:aa|bb)*(?:ab|ba)(?:aa|bb)*(?:ab|ba))*(?:aa|bb)*$

拆解说明

  • (?:aa|bb)*:匹配任意数量的aabb(不改变奇偶性)
  • (?:ab|ba):匹配一次abba(翻转一次奇偶性,从偶偶变奇奇,或奇奇变偶偶)
  • 最前面的(?:(?:aa|bb)*(?:ab|ba)):确保至少有一次奇偶翻转(避免空串)
  • 中间的(?:(?:aa|bb)*(?:ab|ba)(?:aa|bb)*(?:ab|ba))*:匹配0次或多次“两次翻转”(每次两次翻转后回到奇奇状态,总翻转次数保持奇数)
  • 最后的(?:aa|bb)*:允许在末尾添加任意数量的aabb

验证几个例子

  • 空串"":不匹配(正确,因为空串是偶偶)
  • "ab":匹配(1a1b,奇奇)
  • "aaabbb":匹配(3a3b,奇奇)
  • "abab":不匹配(2a2b,偶偶)
  • "aabbab":匹配(3a3b,奇奇)
  • "a":不匹配(1a0b,b是偶数)

内容的提问来源于stack exchange,提问作者DerpDude21

火山引擎 最新活动