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

jv4diomz  于 2023-01-07  发布在  Java
关注(0)|答案(3)|浏览(152)

我尝试使用来自外部源的DOM,其中有一些印地语/阿拉伯语转录的数值,如"۱۶۶۰",当我想将其转换为数值时,我得到NaN
这是怎么回事?
可以尝试的一个小代码片段:

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

yqlxgs2m1#

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("۱۶۶۰") )
5f0d552i

5f0d552i2#

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

vohkndzv3#

下面是一个名为 * 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

有关设置数字格式的详细信息,请参阅this answer

相关问题