You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写JavaScript正则实现Hangman猜词的字符使用次数限制匹配

Hangman 谜题正则匹配方案

问题核心

原有正则仅校验空位字符是否在可选库范围内,没有限制单个字符的总出现次数,会匹配到同字符超量的错误结果(比如示例中可选库o仅1个配额,却匹配到含2个o的alloo)。

实现原理

在原有匹配模式前追加一组负向先行断言,对可选库中的每个字符,单独限制其在整个单词中的总出现次数不得超过可选库中的存量,该逻辑天然兼容模式中已存在的固定字符——断言会从单词起始位置扫描全词统计字符数,固定位置的字符会被自动计入配额消耗。

可直接运行的改造代码

import raw from "./static/wordlist.txt";

/**
 * 构造Hangman匹配正则
 * @param {string} letters 待匹配单词模式,如下划线占位的"___o_"
 * @param {string} bank 可用字符库,如"llaory",字符重复次数代表可用配额
 * @returns {RegExp} 匹配符合条件单词的正则
 */
function buildHangmanReg(letters, bank) {
  // 1. 统计可用字符库中每个字符的最大允许出现次数
  const charLimit = {};
  for (const c of bank) {
    charLimit[c] = (charLimit[c] || 0) + 1;
  }
  // 2. 为每个字符生成负向先行断言:禁止该字符出现次数超过配额
  const assertions = [];
  for (const [char, max] of Object.entries(charLimit)) {
    // 正则含义:如果全词中char出现次数 >= max+1,直接判定匹配失败
    assertions.push(`(?!(?:[^${char}]*${char}){${max + 1}})`);
  }
  // 3. 拼接原有字符匹配规则
  const charPattern = letters.replace(/_/g, `[${bank}]`);
  // 4. 组合成最终正则,\b匹配单词边界
  return new RegExp(`\\b${assertions.join('')}${charPattern}\\b`, 'g');
}

// 示例调用
const pattern = "___o_";
const charBank = "llaory";
const reg = buildHangmanReg(pattern, charBank);

fetch(raw)
  .then(res => res.text())
  .then(wordListText => {
    const matchResult = wordListText.match(reg);
    console.log(matchResult); 
    // 示例输出:['alloy'],超量的'alloo'会被自动过滤
  });

逻辑验证(以题目示例为例)

  1. 统计可选库llaory的字符配额:l:2, a:1, o:1, r:1, y:1
  2. 生成对应断言:
    • 限制l最多出现2次:(?!(?:[^l]*l){3})
    • 限制a最多出现1次:(?!(?:[^a]*a){2})
    • 限制o最多出现1次:(?!(?:[^o]*o){2})
    • 限制r最多出现1次:(?!(?:[^r]*r){2})
    • 限制y最多出现1次:(?!(?:[^y]*y){2})
  3. 匹配校验:
    • alloy:各字符出现次数均未超配额,匹配成功
    • alloo:o共出现2次,触发o对应的负向断言,匹配失败

注意事项

如果可选库中包含]、-、^这类正则特殊字符,需要提前对字符做正则转义处理;常规小写英文字母场景可直接使用上述代码。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 22:31:00