我正在尝试使用来自外部来源的 DOM,其中有一些印地语/阿拉伯语转录的数值,例如"۱۶۶۰"
,当我想将其转换为数值时,我得到NaN
.
这里有什么问题?
要尝试的小代码片段:
alert(Number("۱۶۶۰") + ' - ' + Number("1660"));
我正在尝试使用来自外部来源的 DOM,其中有一些印地语/阿拉伯语转录的数值,例如"۱۶۶۰"
,当我想将其转换为数值时,我得到NaN
.
这里有什么问题?
要尝试的小代码片段:
alert(Number("۱۶۶۰") + ' - ' + Number("1660"));
好吧,该Number
函数确实需要数字 0 到 9,并且不处理阿拉伯数字。您需要自己处理:
function parseArabic(str) {
return Number( str.replace(/[٠١٢٣٤٥٦٧٨٩]/g, function(d) {
return d.charCodeAt(0) - 1632; // Convert Arabic numbers
}).replace(/[۰۱۲۳۴۵۶۷۸۹]/g, function(d) {
return d.charCodeAt(0) - 1776; // Convert Persian numbers
}) );
}
用法:
> parseArabic("۱۶۶۰")
1660
我建议您在较低级别处理它:将阿拉伯数字替换为相应的 ASCII 数字,然后进行转换。
例如:
>a='\u0661\u0666\u0666\u0660'
"١٦٦٠"
>b='\u06f1\u06f6\u06f6\u06f0'
"۱۶۶۰"
>r=/[\u0660-\u0669\u06F0-\u06F9]/g;
/[\u0660-\u0669\u06F0-\u06F9]/g
>a.replace(r,function(c) { return '0123456789'[c.charCodeAt(0)&0xf]; } )
"1660"
>b.replace(r,function(c) { return '0123456789'[c.charCodeAt(0)&0xf]; } )
"1660"
这是一个名为paserNumber的函数,它将表示数字的字符串转换为实际的 JS Number对象。它还可以接受带有分数(十进制数)和阿拉伯语/波斯语/英语千位分隔符的数字字符串。我不知道这个解决方案在性能方面是否是最好的。
function parseNumber(numberText: string) {
return Number(
// Convert Persian (and Arabic) digits to Latin digits
normalizeDigits(numberText)
// Convert Persian/Arabic decimal separator to English decimal separator (dot)
.replace(/٫/g, ".")
// Remove other characters such as thousands separators
.replace(/[^\d.]/g, "")
);
}
const persianDigitsRegex = [/۰/g, /۱/g, /۲/g, /۳/g, /۴/g, /۵/g, /۶/g, /۷/g, /۸/g, /۹/g];
const arabicDigitsRegex = [/٠/g, /١/g, /٢/g, /٣/g, /٤/g, /٥/g, /٦/g, /٧/g, /٨/g, /٩/g];
function normalizeDigits(text: string) {
for (let i = 0; i < 10; i++) {
text = text
.replace(persianDigitsRegex[i], i.toString())
.replace(arabicDigitsRegex[i], i.toString());
}
return text;
}
请注意,解析函数非常宽容,数字字符串可以是波斯/阿拉伯/拉丁数字和分隔符的组合。
获得数字后,您可以使用Number.toLocaleString函数将其格式化回来:
let numberString = "۱۲۳۴.5678";
let number = parseNumber(numberString);
val formatted1 = number.toLocaleString("fa"); // OR "fa-IR" for IRAN
val formatted2 = number.toLocaleString("en"); // OR "en-US" for USA
val formatted3 = number.toLocaleString("ar-EG"); // OR "ar" which uses western numerals
有关格式化数字的更多信息,请参阅此答案。