27

我正在尝试使用来自外部来源的 DOM,其中有一些印地语/阿拉伯语转录的数值,例如"۱۶۶۰",当我想将其转换为数值时,我得到NaN.

这里有什么问题?

要尝试的小代码片段:

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

3 回答 3

53

好吧,该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
于 2013-06-10T13:44:25.293 回答
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"
于 2013-06-10T13:33:29.540 回答
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;
}

请注意,解析函数非常宽容,数字字符串可以是波斯/阿拉伯/拉丁数字和分隔符的组合。

边注

获得数字后,您可以使用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

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

于 2021-12-24T14:58:26.967 回答