用于检查集合的第一个字符和最后一个字符是否不同的正则表达式

Regex expression to check if first and last char of set are different

假设我有一个只有 ab 的字符串,像这样:

aaabbbbababab

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

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

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

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

您可以为第二个字符使用捕获组,并且只匹配与捕获组 1 不同的最后一个字符。

^[ab]([ab])[ab]*(?!)[ab]$
  • ^ 字符串开头
  • [ab]匹配a或b(注意可以省略|因为它表示字符class
  • 中的管道字符
  • ([ab]) 捕获 组 1,匹配 a 或 b
  • [ab]* 可选择匹配 a 或 b
  • (?!) 否定前瞻,断言与使用反向引用在组 1 中捕获的值不同 </code></li> <li><code>[ab]$ 匹配字符串末尾的 a 或 b

Regex demo

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

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

Regex demo

或者如果支持的话,负向回顾也可能有效。 This page 显示 Javascript 和 lookbehinds

的兼容性
^[ab]([ab])[ab]*[ab]$(?<!)

Regex demo

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

^.(.).*(?!).$
  • ^. - 从一个字符开始
  • (.) - 将第二个字符放入捕获组
  • .* - 可选地捕获前进中的一切
  • (?!).$ - 确保最后一个字符与第二个不同

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

出于替代考虑,您可以尝试:

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

网上看到一个demo.

  • ^ - 起始行锚点。
  • [ab]{3,} - 字面上的“a”或“b”的 3 次以上。
  • (?<!^..*(.) - 断言最后一个字符与第二个字符不同的否定回顾。
  • $ - 结束行锚点。

或者,您可以尝试否定前瞻(奇怪的是,这在测试时是最有效的):

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

网上看到一个demo.

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