JavaScript电话验证算法求助:无空格数字词串转数字方法
解决英文数字词转电话号码的问题
嘿,我完全懂你现在的困扰——处理像sixnineone这种连在一起的英文数字词确实有点头疼,尤其是当官方给的正则解法看起来晦涩难懂的时候。我来给你分享几个直观可行的方案,不用硬啃复杂正则:
首先修正你代码里的小问题
先提几个你原代码里容易导致错误的地方:
- 数字0的映射写成了
"o",这会和"one"里的字母o混淆,应该改成"zero" - 数字3的映射是
"tree",明显是笔误,正确是"three" - 清理字符串的正则
/[^1-9a-z]/g会把数字0过滤掉,应该改成/[^0-9a-z]/g
方案一:贪心匹配法(最直观易实现)
这个思路的核心是优先匹配最长的英文数字词,避免短词截断长词(比如先匹配"seven"而不是误匹配"even")。具体步骤:
- 建立正确的数字-英文词映射表
- 把所有英文词按长度从长到短排序
- 从字符串开头逐个尝试匹配最长的词,匹配到就记录对应数字,然后截取剩余字符串继续处理
完整代码实现
function convertWordToNumber(str) { // 建立正确的数字与英文词映射 const numberMap = new Map([ ["zero", 0], ["one", 1], ["two", 2], ["three", 3], ["four", 4], ["five", 5], ["six", 6], ["seven", 7], ["eight", 8], ["nine", 9] ]); // 按单词长度降序排序,优先匹配长单词 const sortedWords = Array.from(numberMap.keys()).sort((a, b) => b.length - a.length); let result = ''; let remainingStr = str.toLowerCase(); while (remainingStr.length > 0) { let matched = false; for (const word of sortedWords) { if (remainingStr.startsWith(word)) { result += numberMap.get(word); remainingStr = remainingStr.slice(word.length); matched = true; break; } } // 遇到无法匹配的字符,返回null表示无效 if (!matched) { return null; } } return result; } function telephoneCheck(str) { // 清理字符串:只保留数字和英文小写字母 let phoneNum = str.toLowerCase().replace(/[^0-9a-z]/g, ""); // 处理纯数字的情况 if (/^\d+$/.test(phoneNum)) { const numLength = phoneNum.length; return numLength === 10 || (numLength === 11 && phoneNum[0] === '1'); } // 处理包含英文数字词的情况 const convertedNum = convertWordToNumber(phoneNum); if (!convertedNum) { return false; // 包含无效英文词,直接返回false } const numLength = convertedNum.length; return numLength === 10 || (numLength === 11 && convertedNum[0] === '1'); } // 测试示例 console.log(telephoneCheck("sixnineone")); // 转换后是"691",长度不够,返回false console.log(telephoneCheck("oneonetwothreefourfivesixseveneightnine")); // 转换后是11位(1+10位),开头为1,返回true console.log(telephoneCheck("sixnineoneoneoneonetwotwo")); // 转换后长度不足,返回false
方案二:动态规划法(处理极端歧义场景)
如果担心出现歧义拆分(不过英文数字词其实没有这种情况),可以用动态规划来记录所有可能的拆分路径,确保得到正确的转换结果。不过对于你的电话号码验证需求,贪心法已经完全足够,这个方案可以作为拓展参考。
核心思路
用一个数组dp,dp[i]表示字符串前i个字符能否被正确拆分,同时记录对应的数字结果。遍历字符串时,检查每个位置能否匹配某个数字词,更新dp数组和结果。
这个方案代码稍复杂,但容错性更强,适合更复杂的文本转换场景。
内容的提问来源于stack exchange,提问作者Eye Patch
相关产品推荐
相关产品推荐

