Преобразовать строку с точкой или запятой в качестве десятичного разделителя в число в JavaScript
Элемент ввода содержит числа a, где запятая или точка используется в качестве десятичного разделителя, а пробел может использоваться для группировки тысяч следующим образом:
'1,2'
'110 000,23'
"100 1,23"
Как преобразовать их в число с плавающей точкой в браузере, используя JavaScript?
JQuery и JQuery UI используются. Number(string)
возвращает NaN и parseFloat()
останавливается на первом пробеле или запятой.
12 ответов
Сначала сделайте замену:
parseFloat(str.replace(',','.').replace(' ',''))
Я понимаю, что опоздал на вечеринку, но я хотел для этого найти решение, которое бы правильно обрабатывало группировку цифр, а также различные десятичные разделители для валют. Поскольку ни один из них полностью не охватил мой сценарий использования, я написал собственное решение, которое может быть полезным для других:
function parsePotentiallyGroupedFloat(stringValue) {
stringValue = stringValue.trim();
var result = stringValue.replace(/[^0-9]/g, '');
if (/[,\.]\d{2}$/.test(stringValue)) {
result = result.replace(/(\d{2})$/, '.$1');
}
return parseFloat(result);
}
Это должно удалить все нецифровые символы, а затем проверить, была ли десятичная точка (или запятая), за которой следуют две цифры, и вставить десятичную точку, если необходимо.
Стоит отметить, что я нацеливался именно на валюту, и поэтому он предполагает либо без десятичных разрядов, либо ровно два. Довольно сложно убедиться в том, является ли первая потенциальная десятичная точка встречной десятичной точкой или символом группировки цифр (например, 1.542
может быть 1542
), если вы не знаете специфику текущей локали, но должно быть достаточно легко адаптировать ее к вашему конкретному варианту использования, изменив \d{2}$
что-то, что будет соответствовать тому, что вы ожидаете после десятичной запятой.
Идеальное решение
accounting.js
это крошечная библиотека JavaScript для форматирования чисел, денег и валюты.
Вы можете заменить все пробелы пустой строкой, все запятые - точками, а затем проанализировать ее.
var str = "110 000,23";
var num = parseFloat(str.replace(/\s/g, "").replace(",", "."));
console.log(num);
В первом я использовал регулярное выражение, чтобы иметь возможность сопоставлять все пробелы, а не только первый.
Все остальные решения требуют, чтобы вы знали формат заранее. Мне нужно было определить (!) Формат в каждом случае, и это то, что я в конечном итоге.
function detectFloat(source) {
let float = accounting.unformat(source);
let posComma = source.indexOf(',');
if (posComma > -1) {
let posDot = source.indexOf('.');
if (posDot > -1 && posComma > posDot) {
let germanFloat = accounting.unformat(source, ',');
if (Math.abs(germanFloat) > Math.abs(float)) {
float = germanFloat;
}
} else {
// source = source.replace(/,/g, '.');
float = accounting.unformat(source, ',');
}
}
return float;
}
Это было проверено в следующих случаях:
const cases = {
"0": 0,
"10.12": 10.12,
"222.20": 222.20,
"-222.20": -222.20,
"+222,20": 222.20,
"-222,20": -222.20,
"-2.222,20": -2222.20,
"-11.111,20": -11111.20,
};
Предложения приветствуются.
Как насчет:
parseFloat(str.replace(' ', '').replace('.', '').replace(',', '.'));
Вот мое решение, у которого нет никаких зависимостей:
return value
.replace(/[^\d\-.,]/g, "") // Basic sanitization. Allows '-' for negative numbers.
.replace(",", ".") // Change all commas to periods.
.replace(/\.(?=.*\.)/g, ""); // Remove all periods except the last one.
(Я пропустил преобразование в число - вероятно, это просто вызов parseFloat, если вас не волнуют проблемы точности JavaScript с числами с плавающей запятой.)
Код предполагает, что:
- В качестве десятичных разделителей используются только запятые и точки. (Я не уверен, существуют ли локали, в которых используются другие.)
- В десятичной части строки разделители не используются.
Вот самодостаточная функция JS, которая решает эту (и другие) проблемы для большинства европейских / американских языков (в первую очередь между фрагментацией номеров США / Германии / Швеции и форматированием... как в OP). Я думаю, что это усовершенствование (и вдохновленное) решением Славы и не имеет никаких зависимостей.
function realParseFloat(s)
{
s = s.replace(/[^\d,.-]/g, ''); // strip everything except numbers, dots, commas and negative sign
if (navigator.language.substring(0, 2) !== "de" && /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(s)) // if not in German locale and matches #,###.######
{
s = s.replace(/,/g, ''); // strip out commas
return parseFloat(s); // convert to number
}
else if (/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(s)) // either in German locale or not match #,###.###### and now matches #.###,########
{
s = s.replace(/\./g, ''); // strip out dots
s = s.replace(/,/g, '.'); // replace comma with dot
return parseFloat(s);
}
else // try #,###.###### anyway
{
s = s.replace(/,/g, ''); // strip out commas
return parseFloat(s); // convert to number
}
}
Попробуй это...
var withComma = "23,3";
var withFloat = "23.3";
var compareValue = function(str){
var fixed = parseFloat(str.replace(',','.'))
if(fixed > 0){
console.log(true)
}else{
console.log(false);
}
}
compareValue(withComma);
compareValue(withFloat);
Этот ответ принимает некоторые крайние случаи, которых нет у других:
- Только разделитель тысяч:
1.000.000
=>1000000
- Экспоненты:
1.000e3
=>1000e3
(1 миллион)
Запустите фрагмент кода, чтобы увидеть весь набор тестов.
const REGEX_UNWANTED_CHARACTERS = /[^\d\-.,]/g
const REGEX_DASHES_EXEPT_BEGINNING = /(?!^)-/g
const REGEX_PERIODS_EXEPT_LAST = /\.(?=.*\.)/g
export function formatNumber(number) {
// Handle exponentials
if ((number.match(/e/g) ?? []).length === 1) {
const numberParts = number.split('e')
return `${formatNumber(numberParts[0])}e${formatNumber(numberParts[1])}`
}
const sanitizedNumber = number
.replace(REGEX_UNWANTED_CHARACTERS, '')
.replace(REGEX_DASHES_EXEPT_BEGINING, '')
// Handle only thousands separator
if (
((sanitizedNumber.match(/,/g) ?? []).length >= 2 && !sanitizedNumber.includes('.')) ||
((sanitizedNumber.match(/\./g) ?? []).length >= 2 && !sanitizedNumber.includes(','))
) {
return sanitizedNumber.replace(/[.,]/g, '')
}
return sanitizedNumber.replace(/,/g, '.').replace(REGEX_PERIODS_EXEPT_LAST, '')
}
function formatNumberToNumber(number) {
return Number(formatNumber(number))
}
От числа к строке валюты легко через Number.prototype.toLocaleString. Однако обратное, похоже, является общей проблемой. Разделитель тысяч и десятичная точка не могут быть получены в стандарте JS.
В этом конкретном вопросе разделитель тысяч является пробелом " "
но во многих случаях это может быть период "."
и десятичная точка может быть запятой ","
, Такие как в 1 000 000,00
или же 1.000.000,00
, Тогда вот как я конвертирую его в правильное число с плавающей точкой.
var price = "1 000.000,99",
value = +price.replace(/(\.|\s)|(\,)/g,(m,p1,p2) => p1 ? "" : ".");
console.log(value);
Таким образом, обратный вызов заменителя занимает "1.000.000,00"
и преобразует его в "1000000.00"
, После этого +
в передней части результирующей строки приводит ее к числу.
Эта функция на самом деле очень удобна. Например, если вы замените p1 = ""
расставаться с p1 = ","
в функции обратного вызова, вход 1.000.000,00
приведет 1,000,000.00