正则表达式字符恰好出现两次

Gra*_*Hat 4 javascript regex string

给定一个字符串数组,测试是否有任何字符恰好出现两次。

样本:

const input = ['asdf', 'fdas', 'asds', 'd fm', 'dfaa', 'aaaa', 'aabb', 'aaabb'];
const output = ['asds', 'dfaa', 'aabb', 'aaabb'];
Run Code Online (Sandbox Code Playgroud)

我试过这样

/(?:^|(.)(?!\1))([A-Za-z0-9])\2(?!\2)/
Run Code Online (Sandbox Code Playgroud)

但我只得到这些字符串:['dfaa', 'aabb', 'aaabb']

请问有什么建议吗?

Wik*_*żew 5

您可以使用

/(.)(?<=^(?:(?!\1).)*\1(?=(?:(?!\1).)*\1(?:(?!\1).)*$))/s
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示请注意,由于我们只查找第一个匹配项,因此没有g标志。细节

  • (.)- 捕获到第 1 组的任何一个字符:
  • (?<=- 开始积极的向后看,立即在左边,应该有
    • ^- 字符串的开头
    • (?:(?!\1).)*- 任何字符,尽可能多,除了捕获到组 1 的字符之外
    • \1- 捕获到第 1 组的相同字符
    • (?=(?:(?!\1).)*\1(?:(?!\1).)*$)- 正向先行,需要除组 1 中的字符之外的任何零个或多个字符,然后是与组 1 中捕获的相同的字符,以及除组 1 中的字符之外的任何零个或多个字符,直到字符串末尾
  • )- 回顾结束。

内部带有调和的贪婪标记的环视确保捕获的字符在字符串中只出现两次。

请参阅 JavaScript 演示:

const input = ['asdf', 'fdas', 'asds', 'd fm', 'dfaa', 'aaaa', 'aabb', 'aaabb'];
const re = /(.)(?<=^(?:(?!\1).)*\1(?=(?:(?!\1).)*\1(?:(?!\1).)*$))/s;
for (const s of input) {
   console.log(s, '=>', re.test(s))
}
Run Code Online (Sandbox Code Playgroud)