Существует ли какой-либо стандартный API-интерфейс JavaScript для анализа числа в соответствии с локалью? - PullRequest
1 голос
/ 26 марта 2019

Для форматирования числа в соответствии с языковым стандартом существует стандартный JavaScript API: Intl.NumberFormat

Но для обратного действия при разборе строки на число я не могу найти ни одного стандартного API, поддерживающего локали:

  • Число не поддерживает аргументы локали.
  • parseFloat и parseInt также не поддерживают аргументы локали.

Действительно ли нет стандартного API-интерфейса JavaScript для анализа строки по числу в соответствии с локалью?

А если нет: существует ли какой-либо рынок, библиотеки с открытым исходным кодом для этого?

1 Ответ

1 голос
/ 27 марта 2019

Пакет NPM d2l-intl предоставляет анализатор, чувствительный к локали.

const { NumberFormat, NumberParse } = require('d2l-intl');
const formatter = new NumberFormat('es');
const parser = new NumberParse('es');
const number = 1234.5;
console.log(formatter.format(number));                 // 1.234,5
console.log(parser.parse(formatter.format(1234.5)));   // 1234.5

К сожалению, эта библиотека поставляется только с поддержкой горстки локалей из коробки.Он также использует parseInt, который поддерживает только западно-арабские цифры, поэтому для локалей, в которых используются разные системы счисления, вам нужно стать более умным. Вот одно решение Я нашел Майк Босток .Я не хочу брать кредит за это, но я воспроизвел это здесь для потомков (с некоторыми небольшими изменениями, основанными на моих собственных предпочтениях):

class NumberParser {
  constructor(locale) {
    const format = new Intl.NumberFormat(locale);
    const parts = format.formatToParts(12345.6);
    const numerals = Array.from({ length: 10 }).map((_, i) => format.format(i));
    const index = new Map(numerals.map((d, i) => [d, i]));
    this._group = new RegExp(`[${parts.find(d => d.type === "group").value}]`, "g");
    this._decimal = new RegExp(`[${parts.find(d => d.type === "decimal").value}]`);
    this._numeral = new RegExp(`[${numerals.join("")}]`, "g");
    this._index = d => index.get(d);
  }
  parse(string) {
    return (string = string.trim()
      .replace(this._group, "")
      .replace(this._decimal, ".")
      .replace(this._numeral, this._index)) ? +string : NaN;
  }
}

const formatter = new Intl.NumberFormat('ar-EG');
const parser = new NumberParser('ar-EG');
console.log(formatter.format(1234.5));               // ١٬٢٣٤٫٥
console.log(parser.parse(formatter.format(1234.5))); // 1234.5
...