Ответ 1
Да удалите запятые:
parseFloat(yournumber.replace(/,/g, ''));
У меня есть 2,299.00
как строка, и я пытаюсь разобрать его на число. Я попытался использовать parseFloat
, что приводит к 2. Я думаю, что запятая является проблемой, но как я могу решить эту проблему правильно? Просто удалите запятую?
var x = parseFloat("2,299.00")
alert(x);
Да удалите запятые:
parseFloat(yournumber.replace(/,/g, ''));
Удаление запятых является потенциально опасным, поскольку, как отмечали другие комментарии, многие локали используют запятую для обозначения чего-то другого (например, десятичного).
Я не знаю, откуда вы взяли свою строку, но в некоторых местах мира "2,299.00"
= 2.299
Объект Intl
мог бы стать хорошим способом решения этой проблемы, но каким-то образом им удалось отправить спецификацию только с помощью API Intl.NumberFormat.format()
и не parse
: (
Единственный способ разобрать строку с числовыми числовыми символами в ней на распознаваемый машиной номер любым разумным способом i18n - использовать библиотеку, которая использует данные CLDR, чтобы покрыть все возможные способы форматирования строк чисел http://cldr.unicode.org/
Два лучших варианта JS, с которыми я столкнулся до сих пор:
В современных браузерах вы можете использовать встроенный 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 }`);
}
Удалите все, что не является цифрой, десятичной точкой или значком минуса (-
):
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, "");
Обычно вам следует использовать поля ввода, которые не допускают ввода свободного текста для числовых значений. Но могут быть случаи, когда вам нужно угадать формат ввода. Например, 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.
Это сбивало с толку, что они включали 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, "."));
Это упрощенная ненавязчивая оболочка для функции 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);
}
Если вы хотите избежать проблемы, которую опубликовал Дэвид Мейстер, и уверены в количестве десятичных знаков, вы можете заменить все точки и запятые и разделить на 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(...).
Все эти ответы терпят неудачу, если у вас есть число в миллионах.
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(''));
Замените запятую пустой строкой:
var x = parseFloat("2,299.00".replace(",",""))
alert(x);
Если вы хотите, чтобы 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, ""));
Если у вас есть небольшой набор локалей для поддержки, вам, вероятно, будет лучше, просто скопировав несколько простых правил:
function parseNumber(str, locale) {
let radix = ',';
if (locale.match(/(en|th)([-_].+)?/)) {
radix = '.';
}
return Number(str
.replace(new RegExp('[^\\d\\' + radix + ']', 'g'), '')
.replace(radix, '.'));
}
Связанный ответ, но если вы хотите запустить очистку ввода значений пользователем в форму, вот что вы можете сделать:
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
}