JavaScript错词生成器:如何忽略作为首尾字符的标点符号?
解决单词首尾标点忽略问题的实现方案
要解决这个问题,核心是先定位单词中真正的首尾字母(跳过前后的标点符号),只打乱首尾字母之间的内部字母,前后的标点保持原位置不变。
修改后的完整代码
// Fisher-Yates洗牌算法,比原交换方式更随机 function shuffleArray(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } } let words = document.body.innerText.split(" "); let scrambled = ""; for (let i = 0; i < words.length; i++) { const word = words[i]; if (!word) { scrambled += " "; continue; } // 找到第一个字母的索引(跳过开头的标点) let startIdx = 0; while (startIdx < word.length && !/[a-zA-Z]/.test(word[startIdx])) { startIdx++; } // 找到最后一个字母的索引(跳过结尾的标点) let endIdx = word.length - 1; while (endIdx >= 0 && !/[a-zA-Z]/.test(word[endIdx])) { endIdx--; } // 边界情况:无字母/只有一个字母,直接保留原单词 if (startIdx >= endIdx) { scrambled += word + " "; continue; } // 拆分单词为字符数组 const letters = word.split(""); // 提取需要打乱的中间字母部分 const middleLetters = letters.slice(startIdx + 1, endIdx); // 打乱中间字母 shuffleArray(middleLetters); // 将打乱后的字母放回原数组 letters.splice(startIdx + 1, middleLetters.length, ...middleLetters); // 拼接结果 scrambled += letters.join("") + " "; } document.body.innerText = scrambled.trim();
关键逻辑说明
- 首尾字母定位:通过循环和正则
/[a-zA-Z]/匹配字母,跳过单词开头和结尾的所有标点符号,找到真正的首尾字母位置。 - 边界处理:如果单词全是标点、只有一个字母,直接保留原内容不处理。
- 更合理的洗牌算法:替换原有的交换逻辑为Fisher-Yates洗牌,保证打乱结果的随机性更均匀。
- 标点保留:只修改首尾字母之间的字符,前后的标点完全保持原位置和顺序。
内容的提问来源于stack exchange,提问作者Ryan Perez
相关产品推荐
相关产品推荐

