根据电话键盘将电话号码中的字母转换为数字


Convert letters in phone number to numbers according to phone keypad

我试图找到最简单(或至少最短)的方法,做到以下:

从输入字段中获取任意文本,并按如下方式进行转换:

abc => 2
def => 3
ghi => 4
...
wxyz => 9

*不属于英文字母的任何其他字符将被转换为'#'(或任何其他特殊字符)。

这可能听起来很简单,但代码可以非常简单和优雅,这就是我所寻找的,更少的行在php或js/jquery脚本。如果它转换为"abc", "def",我可以完成其余的

创建一个关联数组,将A映射到2,B映射到2,C映射到2,D映射到3,等等

遍历字符串,每次一个字符。如果在数组中找到一个字符,将其连接到输出中;如果没有,将"#"连接到输出。您可能希望首先将字符串转换为全大写或全小写。

编辑补充:我没有包括代码,因为OP似乎知道JavaScript和PHP,当然,代码会有所不同,但原则是相同的。

如果绝对肯定字符串是ASCII/UTF-8/ISO-8859格式,则可以利用大写字母占用十进制65到90码位的事实,并且为从2到9的每个数字分配三个字母,从而计算结果。(请注意,美国电话中没有Q, Z映射为零。)然而,这并不是那么优雅,而是过于复杂。

今天早些时候有人提醒我:

"调试是编写代码的两倍难。因此,如果你尽可能聪明地编写代码,从定义上讲,没有聪明到调试它。——Brian Kernighan和P.J. Plauger,编程风格的要素

您可以使用str_replace($searchArr, $replaceArr, $string)将"搜索数组"中的任何内容替换为"替换数组"中的相应值。你可以像这样填充数组

$string = "dhebfctgddekj";
$pattern = array();
$replacement = array();
for($i = 97; $i < 123; $i++) //Ascii 97 = a to ascii 122 = z
{
   $pattern[] = chr($i); //Convert the ascii to a character
}
$r = array(3,3,3,3,3,4,3,4); //How many characters each number has
$j = 2;
foreach($r as $val)
{
    for($i = 0; $i < $val; $i++)
        $replacement[] = $j;
    $j++;
}
$string2 = str_replace($pattern, $replacement, strtolower($string));
echo $string2;
$subject = '0900ABCDEF'    
$ReplacementPattern = array(
    'a' => '2',
    'b' => '2',
    'c' => '2',
    'd' => '3',
    'e' => '3',
    'f' => '3',
    'g' => '4',
    'h' => '4',
    'i' => '4',
    'j' => '5',
    'k' => '5',
    'l' => '5',
    'm' => '6',
    'n' => '6',
    'o' => '6',
    'p' => '7',
    'q' => '7',
    'r' => '7',
    's' => '7',
    't' => '8',
    'u' => '8',
    'v' => '8',
    'w' => '9',
    'x' => '9',
    'y' => '9',
    'z' => '9',
    '+' => '00',
    ' ' => '',
);
echo str_ireplace(array_keys($ReplacementPattern), array_values($ReplacementPattern), $subject);

javascript中的一行代码:

phoneStr.replace(/./g, x => 
    '22233344455566677778889999'[(x.charCodeAt()-65)%32] || x
);

如果你想更清楚,你可以用[x.toLowerCase().charCodeAt()-97]

演示(粘贴在适当命名的函数中):

> phoneToKeypad('+1-800-abc-WXYZ')
"+1-800-222-9999"

如果你需要,你也可以使用Array.from(phoneStr, x => x)来处理数组表示,然后.join('')稍后返回到字符串。

通过预处理适当地剥离脏输入(例如连字符,括号等):

phoneStr.replace(/[^0-9*#+a-zA-Z]/g, '').replace( ... etcetc

当然,你需要在服务器端做这样的清理,所以你不能只依赖于客户端javascript(除非你的服务器也在javascript中)。

键盘的布局参考ISO/IEC 9995-8。然而,请注意(根据我非常粗略的研究)有太多的国际标准,例如欧洲的184页ETSI ES 202 130标准。

下面是我用来将文本转换为电话键盘号码的javascript函数:

const textToKeypadNumber = (text) => {
  const phoneCharMap = {
    a: "2",
    b: "2",
    c: "2",
    d: "3",
    e: "3",
    f: "3",
    g: "4",
    h: "4",
    i: "4",
    j: "5",
    k: "5",
    l: "5",
    m: "6",
    n: "6",
    o: "6",
    p: "7",
    q: "7",
    r: "7",
    s: "7",
    t: "8",
    u: "8",
    v: "8",
    w: "9",
    x: "9",
    y: "9",
    z: "9",
    "+": "00",
    " ": ""
  };
  const _text = text.split("");
  return _text
    .map(char => {
      const number = phoneCharMap[char.toLowerCase()];
      if (number) return phoneCharMap[char.toLowerCase()];
      return char;
    })
    .join("");
}

像这样使用:

textToKeypadNumber('1-800-MY-APPLE'); // 1-800-69-27753

为了遵守ISO/IEC 9995-8(这是我在这个任务中想到的字母到数字的转换),PHP的strtr()将使用两个紧凑的字符串。

如果可以使用小写字母,则在翻译之前先呼叫strtoupper(),但每当我看到用字母广告的电话号码时,它们都是大写的。

代码(演示):

$phone = '1300EXAMPLE';
echo strtr(
         $phone,
         'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
         '22233344455566677778889999'
     );
// 13003926753

如果要将所有剩余的非数字消毒为#,则使用preg_replace():

echo preg_replace(
         '/'D+/',
         '#',
         strtr(
             $phone,
             'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
             '22233344455566677778889999'
         )
     );