【问题标题】:Regex expression to check if first and last char of set are different正则表达式检查集合的第一个和最后一个字符是否不同
【发布时间】:2021-07-19 20:25:02
【问题描述】:

假设我有一串只有 ab 的字符串,如下所示:

aaabbbbababab

如何构造一个正则表达式,只有当第二个和最后一个字符不同时才匹配给定的字符串?

这是我目前的尝试,完全相反(例如,如果第二个和最后一个字符相同,则匹配):

^[ab]([ab])[ab]*\1$

我正在使用正则表达式的 ECMAScript 实现。

【问题讨论】:

  • ab 重要吗?正则表达式是否还需要验证这些是字符串中仅有的 2 个字符?
  • 是的,如果第二个字符是a,那么最后一个字符必须是b,而不是其他字符。
  • 哦,好吧,所以stackoverflow.com/a/67267084/2191572 是正确的,但如果ab 不重要,我确实提供了一个通用的解决方案。
  • 您是否也需要允许单个字符,例如“a”?也许你可以试试:^(?!.(.).*\1$)[ab]+$
  • 不,我希望字符串的长度 > 2

标签: javascript regex regex-lookarounds regex-negation


【解决方案1】:

只是为了替代,你可以尝试:

^[ab]{3,}(?<!^.\1.*(.))$

在线查看demo

  • ^ - 起始线锚点。
  • [ab]{3,} - 3 次以上的字面意思是“a”或“b”。
  • (?&lt;!^.\1.*(.) - 否定后视断言最后一个字符与第二个字符不同。
  • $ - 结束线锚。

或者,您可以尝试负前瞻(奇怪的是,这在测试时效率最高):

^(?!.(.).*\1$)[ab]{3,}$

在线查看demo

  • ^ - 起始线锚点。
  • (?!.(.).*\1$) - 断言第二个字符的负前瞻与结束行锚点之前的最后一个字符不同。
  • [ab]{3,} - 3 次以上的字面意思是“a”或“b”。
  • $ - 结束线锚。

【讨论】:

    【解决方案2】:

    您可以为第二个字符使用一个捕获组,如果它与捕获组 1 不同,则仅匹配最后一个字符。

    ^[ab]([ab])[ab]*(?!\1)[ab]$
    
    • ^ 字符串开始
    • [ab] 匹配 a 或 b(请注意,您可以省略 |,因为它表示字符类中的管道字符
    • ([ab]) 捕获组 1,匹配 a 或 b
    • [ab]* 可选择匹配 a 或 b
    • (?!\1) 负前瞻,使用反向引用 \1 断言与第 1 组中捕获的值不同的值
    • [ab]$ 匹配字符串末尾的 a 或 b

    Regex demo

    另一种选择是在捕获组之后立即进行断言

    ^[ab]([ab])(?![ab]*\1$)[ab]*$
    

    Regex demo

    或者,如果支持,负面的后视也可能起作用。 This page 显示了对 Javascript 和lookbehinds 的兼容性

    ^[ab]([ab])[ab]*[ab]$(?<!\1)
    

    Regex demo

    【讨论】:

    • 您为什么要切换到[a-b] 来获取其中一个 char 类?
    • @MonkeyZeus 这是一个错字,让我更新一下:-)
    【解决方案3】:

    如果您不必验证整个字符串是一堆abs,那么我会选择通用的,例如:

    ^.(.).*(?!\1).$
    
    • ^. - 以一个字符开头
    • (.) - 将第二个字符放入捕获组中
    • .* - 可以选择捕获前进的所有内容
    • (?!\1).$ - 确保最终字符与第二个字符不同

    https://regex101.com/r/k47PUu/1/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-12
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 2014-11-07
      • 2022-06-15
      • 1970-01-01
      相关资源
      最近更新 更多