JavaScript无法将印地语/阿拉伯语数字转换为实际数字变量

28

我正试图使用来自外部来源的DOM,其中包含一些以印地语/阿拉伯语转录的数字值,例如"۱۶۶۰",但当我想将其转换为数字值时,我得到了NaN

这里出了什么问题?

一个可以尝试的小代码片段:

alert(Number("۱۶۶۰") + ' - ' + Number("1660"));

3
我在Chrome的控制台中尝试了你的代码,结果显示“TypeError: Object function Number() { [native code] } has no method 'parseLocale'”。我查阅了Mozilla的文档,但没有找到相关信息。这是仅限于IE吗? - Geeky Guy
1
不需要使用 parseLocale 方法。 - Saeed Neamati
2
JavaScript目前还不支持解析这样的数字,详情请参考:http://wiki.ecmascript.org/doku.php?id=globalization:globalization 和 http://es5.github.io/#x7.8.3 和 http://es5.github.io/#x15.1.2.2。 - Jonathan Lonowski
3个回答

55

好的,Number函数只接受0到9的数字,不支持阿拉伯数字,您需要自行处理。

function parseArabic(str) {
  return Number(str
    .replace(/[٠١٢٣٤٥٦٧٨٩]/g, d => d.charCodeAt(0) - 1632) // convert Arabic digits
    .replace(/[۰۱۲۳۴۵۶۷۸۹]/g, d => d.charCodeAt(0) - 1776) // convert Persian digits
  );
}
// usage example:
console.log( parseArabic("۱۶۶۰") )


1
第一个数字集是阿拉伯数字,第二个是波斯数字。 - Ahmad Ahmadi
1
因为我找不到其他方法的答案,所以在这里提供(仅限阿拉伯语)function eurToArab(num) { return num.toString().replace(/\d/g, function(d) { return String.fromCharCode(parseInt(d[0], 10) + 1632); }); } - Haroen Viaene
有没有不使用基数10的数字系统的示例,我们可能需要处理? - Richard Corfield
@RichardCorfield 在这个问题中,没有任何重要性,至少不会有关系。 - Bergi

15

我建议您从更低的层面处理它:用相应的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"

0
这里有一个名为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;
}

请注意,parse函数非常宽容,数字字符串可以是波斯/阿拉伯/拉丁数字和分隔符的组合。
附注:获取Number后,您可以使用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

有关数字格式的更多信息,请参阅此答案


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接