首页 > 解决方案 > 正则表达式模式匹配单词的字母组合

问题描述

目前我正在为孩子们开发益智游戏,玩家需要从网格中选择正确的单词。我用正则表达式来匹配这个词。

举个例子,我曾经([D|E|C|K]){4}匹配DECK,因为玩家应该能够选择不完全按照D->E->C->K顺序的单词。玩家可以选择KDECEDCKKCED或任何顺序。

我通过使用([D|E|C|K]){4}.

但是在这里我遇到了问题,这种模式匹配EEEEDDDDDKDK等。只是集合中 4 个字符的任意组合。

任何想法如何修改正则表达式以获得我想要的结果?

提前致谢。

在此处输入图像描述

标签: regex

解决方案


基本上,这不是正则表达式的好工作,因为这不是常规语言。您最好按照一个简单的算法将输入字符串拆分为字符,对它们进行排序,然后重新连接成一个字符串,对搜索字符串执行相同的操作,然后比较结果。

查看带有单词的 JavaScript 演示TALL

const strings = ['TALL','LATL','TLAL','TTAL','AATT','ATL','STL'];
const search = 'TALL';
const compare_with = search.split("").sort().join("");
for (let s of strings) {
    console.log(s, ':', s.split("").sort().join("") == compare_with );
}

我们可以用正则表达式来做吗?在 .NET 中,您可以使用平衡构造,它是一种解决方案,而不是一种解决方法。

场景 1:.NET 正则表达式引擎特定的解决方案

假设您的搜索词是TALL,您可以构建一个正则表达式

^(?:(T)|(A)|(L)|(L)){4}$(?<-1>)(?<-2>)(?<-3>)(?<-4>)

请参阅正则表达式演示

细节

  • ^- 字符串的开始
  • (?:(T)|(A)|(L)|(L)){4}- 匹配 4 次出现的非捕获组
    • (T)-T推送到第 1 组捕获堆栈
    • |(A)- 或A推送到第 2 组捕获堆栈
    • |(L)- 或L推送到第 3 组捕获堆栈
    • |(L)- 或L推送到第 4 组捕获堆栈
  • $- 字符串结束
  • (?<-1>)(?<-2>)(?<-3>)(?<-4>)- 从每个捕获组中弹出一个值。如果任何组捕获堆栈不为空,则返回 false 并导致不匹配,否则存在匹配。

场景 2:在所有字符都是唯一的情况下,前瞻 basd 解决方法

您可以将范围中的每个字母匹配并捕获到一个单独的捕获组中,并在每个后续捕获组之前添加一个负前瞻以避免匹配之前匹配的字母。

正则表达式看起来像

^([DECK])(?!\1)([DECK])(?!\1|\2)([DECK])(?!\1|\2|\3)([DECK])$

查看正则表达式演示

细节

  • ^- 字符串的开始
  • ([DECK])- 第 1组:字母D、、、ECK
  • (?!\1)- 下一个字符不能是第 1 组捕获的字符
  • ([DECK])- 第 2组:字母D、、、ECK
  • (?!\1|\2)([DECK])- 下一个字母不能等于第一个和第二个
  • (?!\1|\2|\3)([DECK])- 下一个字母不能等于第一个、第二个和第三个
  • $- 字符串结束

推荐阅读