Подтвердить что ты не робот

Как я могу разобрать строку с разделителем запятой на число?

У меня есть 2,299.00 как строка, и я пытаюсь разобрать его на число. Я попытался использовать parseFloat, что приводит к 2. Я думаю, что запятая является проблемой, но как я могу решить эту проблему правильно? Просто удалите запятую?

var x = parseFloat("2,299.00")
alert(x);
4b9b3361

Ответ 1

Да удалите запятые:

parseFloat(yournumber.replace(/,/g, ''));

Ответ 2

Удаление запятых является потенциально опасным, поскольку, как отмечали другие комментарии, многие локали используют запятую для обозначения чего-то другого (например, десятичного).

Я не знаю, откуда вы взяли свою строку, но в некоторых местах мира "2,299.00"= 2.299

Объект Intl мог бы стать хорошим способом решения этой проблемы, но каким-то образом им удалось отправить спецификацию только с помощью API Intl.NumberFormat.format() и не parse: (

Единственный способ разобрать строку с числовыми числовыми символами в ней на распознаваемый машиной номер любым разумным способом i18n - использовать библиотеку, которая использует данные CLDR, чтобы покрыть все возможные способы форматирования строк чисел http://cldr.unicode.org/

Два лучших варианта JS, с которыми я столкнулся до сих пор:

Ответ 3

В современных браузерах вы можете использовать встроенный Intl.NumberFormat для определения форматирования номера браузера и нормализации ввода для соответствия.

function parseNumber(value, locale = navigator.language) {
  const example = Intl.NumberFormat(locale).format('1.1');
  const cleanPattern = new RegExp(`[^-+0-9${ example.charAt( 1 ) }]`, 'g');
  const cleaned = value.replace(cleanPattern, '');
  const normalized = cleaned.replace(example.charAt(1), '.');

  return parseFloat(normalized);
}

const corpus = {
  '1.123': {
    expected: 1.123,
    locale: 'en-US'
  },
  '1,123': {
    expected: 1123,
    locale: 'en-US'
  },
  '2.123': {
    expected: 2123,
    locale: 'fr-FR'
  },
  '2,123': {
    expected: 2.123,
    locale: 'fr-FR'
  },
}


for (const candidate in corpus) {
  const {
    locale,
    expected
  } = corpus[candidate];
  const parsed = parseNumber(candidate, locale);

  console.log(`${ candidate } in ${ corpus[ candidate ].locale } == ${ expected }? ${ parsed === expected }`);
}

Ответ 4

Удалите все, что не является цифрой, десятичной точкой или значком минуса (-):

var str = "2,299.00";
str = str.replace(/[^\d\.\-]/g, ""); // You might also include + if you want them to be able to type it
var num = parseFloat(str);

Обновлена ​​скрипка

Обратите внимание, что это не будет работать для чисел в научной нотации. Если вы хотите, измените строку replace, чтобы добавить e, e и + в список допустимых символов:

str = str.replace(/[^\d\.\-eE+]/g, "");

Ответ 5

Обычно вам следует использовать поля ввода, которые не допускают ввода свободного текста для числовых значений. Но могут быть случаи, когда вам нужно угадать формат ввода. Например, 1.234.56 в Германии означает 1234.56 в США. См. Https://salesforce.stackexchange.com/a/21404 для списка стран, которые используют запятую как десятичную.

Я использую следующую функцию, чтобы сделать наилучшее предположение и удалить все нечисловые символы:

function parseNumber(strg) {
    var strg = strg || "";
    var decimal = '.';
    strg = strg.replace(/[^0-9$.,]/g, '');
    if(strg.indexOf(',') > strg.indexOf('.')) decimal = ',';
    if((strg.match(new RegExp("\\" + decimal,"g")) || []).length > 1) decimal="";
    if (decimal != "" && (strg.length - strg.indexOf(decimal) - 1 == 3) && strg.indexOf("0" + decimal)!==0) decimal = "";
    strg = strg.replace(new RegExp("[^0-9$" + decimal + "]","g"), "");
    strg = strg.replace(',', '.');
    return parseFloat(strg);
}   

Попробуйте здесь: https://plnkr.co/edit/9p5Y6H?p=preview

Примеры:

1.234,56 € => 1234.56
1,234.56USD => 1234.56
1,234,567€ => 1234567
1.234.567 => 1234567
1,234.567 => 1234.567
1.234 => 1234 // might be wrong - best guess
1,234 => 1234 // might be wrong - best guess
1.2345 => 1.2345
0,123 => 0.123

Функция имеет одну слабую точку: невозможно угадать формат, если у вас есть 1,123 или 1.123, потому что в зависимости от формата локали они могут быть запятой или разделителем тысяч. В этом специальном случае функция будет рассматривать разделитель как разделитель тысяч и возвращает 1123.

Ответ 6

Это сбивало с толку, что они включали toLocaleString, но не метод parse. По крайней мере toLocaleString без аргументов хорошо поддерживается в IE6+.

Для решения i18n я придумал следующее:

Сначала определите десятичный разделитель локали пользователя:

var decimalSeparator = 1.1;
decimalSeparator = decimalSeparator.toLocaleString().substring(1, 2);

Затем нормализуйте число, если в String имеется более одного десятичного разделителя:

var pattern = "([" + decimalSeparator + "])(?=.*\\1)";separator
var formatted = valor.replace(new RegExp(pattern, "g"), "");

Наконец, удалите все, что не является числом или десятичным разделителем:

formatted = formatted.replace(new RegExp("[^0-9" + decimalSeparator + "]", "g"), '');
return Number(formatted.replace(decimalSeparator, "."));

Ответ 7

Это упрощенная ненавязчивая оболочка для функции parseFloat.

function parseLocaleNumber(str) {
  // Detect the user locale decimal separator:
  var decimalSeparator = (1.1).toLocaleString().substring(1, 2);
  // Detect the user locale thousand separator:
  var thousandSeparator = (1000).toLocaleString().substring(1, 2);
  // In case there are locales that don't use a thousand separator
  if (thousandSeparator.match(/\d/))
    thousandSeparator = '';

  str = str
    .replace(new RegExp(thousandSeparator, 'g'), '')
    .replace(new RegExp(decimalSeparator), '.')

  return parseFloat(str);
}

Ответ 8

Если вы хотите избежать проблемы, которую опубликовал Дэвид Мейстер, и уверены в количестве десятичных знаков, вы можете заменить все точки и запятые и разделить на 100, например:

var value = "2,299.00";
var amount = parseFloat(value.replace(/"|\,|\./g, ''))/100;

или если у вас есть 3 десятичных знака

var value = "2,299.001";
var amount = parseFloat(value.replace(/"|\,|\./g, ''))/1000;

Вам решать, хотите ли вы использовать parseInt, parseFloat или Number. Также Если вы хотите сохранить количество десятичных разрядов, вы можете использовать функцию .toFixed(...).

Ответ 9

Все эти ответы терпят неудачу, если у вас есть число в миллионах.

3,456,789 просто вернет 3456 с помощью метода замены.

Самый правильный ответ для простого удаления запятых должен быть.

var number = '3,456,789.12';
number.split(',').join('');
/* number now equips 3456789.12 */
parseFloat(number);

Или просто написано.

number = parseFloat(number.split(',').join(''));

Ответ 10

Замените запятую пустой строкой:

var x = parseFloat("2,299.00".replace(",",""))
alert(x);

Ответ 11

Если вы хотите, чтобы l10n отвечал так. В примере используется валюта, но вам это не нужно. Для поддержки старых браузеров библиотека Intl должна быть заполнена полисом.

var value = "2,299.00";
var currencyId = "USD";
var nf = new Intl.NumberFormat(undefined, {style:'currency', currency: currencyId, minimumFractionDigits: 2});

value = nf.format(value.replace(/,/g, ""));

Ответ 12

Если у вас есть небольшой набор локалей для поддержки, вам, вероятно, будет лучше, просто скопировав несколько простых правил:

function parseNumber(str, locale) {
  let radix = ',';
  if (locale.match(/(en|th)([-_].+)?/)) {
    radix = '.';
  }
  return Number(str
    .replace(new RegExp('[^\\d\\' + radix + ']', 'g'), '')
    .replace(radix, '.'));
}

Ответ 13

Связанный ответ, но если вы хотите запустить очистку ввода значений пользователем в форму, вот что вы можете сделать:

const numFormatter = new Intl.NumberFormat('en-US', {
  style: "decimal",
  maximumFractionDigits: 2
})

// Good Inputs
parseFloat(numFormatter.format('1234').replace(/,/g,"")) // 1234
parseFloat(numFormatter.format('123').replace(/,/g,"")) // 123

// 3rd decimal place rounds to nearest
parseFloat(numFormatter.format('1234.233').replace(/,/g,"")); // 1234.23
parseFloat(numFormatter.format('1234.239').replace(/,/g,"")); // 1234.24

// Bad Inputs
parseFloat(numFormatter.format('1234.233a').replace(/,/g,"")); // NaN
parseFloat(numFormatter.format('$1234.23').replace(/,/g,"")); // NaN

// Edge Cases
parseFloat(numFormatter.format(true).replace(/,/g,"")) // 1
parseFloat(numFormatter.format(false).replace(/,/g,"")) // 0
parseFloat(numFormatter.format(NaN).replace(/,/g,"")) // NaN

Используйте международную дату по местному времени через format. Это очищает любые неверные данные, если они есть, возвращает строку NaN, которую вы можете проверить. В настоящее время нет способа удалить запятые как часть локали (по состоянию на 10.12.19), поэтому вы можете использовать команду regex для удаления запятых с помощью replace.

ParseFloat преобразует определение этого типа из строки в число

Если вы используете React, ваша функция вычисления может выглядеть следующим образом:

updateCalculationInput = (e) => {
    let value;
    value = numFormatter.format(e.target.value); // 123,456.78 - 3rd decimal rounds to nearest number as expected
    if(value === 'NaN') return; // locale returns string of NaN if fail
    value = value.replace(/,/g, ""); // remove commas
    value = parseFloat(value); // now parse to float should always be clean input

    // Do the actual math and setState calls here
}