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

JavaScript电话验证算法求助:无空格数字词串转数字方法

解决英文数字词转电话号码的问题

嘿,我完全懂你现在的困扰——处理像sixnineone这种连在一起的英文数字词确实有点头疼,尤其是当官方给的正则解法看起来晦涩难懂的时候。我来给你分享几个直观可行的方案,不用硬啃复杂正则:

首先修正你代码里的小问题

先提几个你原代码里容易导致错误的地方:

  • 数字0的映射写成了"o",这会和"one"里的字母o混淆,应该改成"zero"
  • 数字3的映射是"tree",明显是笔误,正确是"three"
  • 清理字符串的正则/[^1-9a-z]/g会把数字0过滤掉,应该改成/[^0-9a-z]/g

方案一:贪心匹配法(最直观易实现)

这个思路的核心是优先匹配最长的英文数字词,避免短词截断长词(比如先匹配"seven"而不是误匹配"even")。具体步骤:

  1. 建立正确的数字-英文词映射表
  2. 把所有英文词按长度从长到短排序
  3. 从字符串开头逐个尝试匹配最长的词,匹配到就记录对应数字,然后截取剩余字符串继续处理

完整代码实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:49:50