我试图找到最简单(或至少最短)的方法,做到以下:
从输入字段中获取任意文本,并按如下方式进行转换:
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'
)
);