developer tip

쉼표 천 단위 구분 기호가있는 문자열을 숫자로 구문 분석하려면 어떻게해야합니까?

copycodes 2020. 10. 25. 12:28
반응형

쉼표 천 단위 구분 기호가있는 문자열을 숫자로 구문 분석하려면 어떻게해야합니까?


나는 2,299.00문자열로 가지고 있으며 그것을 숫자로 구문 분석하려고합니다. 를 사용해 보았습니다. parseFloat결과는 2입니다. 쉼표가 문제인 것 같지만이 문제를 올바른 방법으로 해결하려면 어떻게해야합니까? 쉼표 만 제거 하시겠습니까?

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


예 쉼표를 제거하십시오.

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

쉼표를 제거하는 것은 잠재적으로 위험합니다. 다른 사람들이 주석에서 언급했듯이 많은 로케일은 쉼표를 사용하여 다른 것을 의미합니다 (소수점 등).

나는 당신이 당신의 끈을 어디서 얻었는지 모르지만 세계의 어떤 곳에서 "2,299.00"=2.299

Intl객체는이 문제를 해결하는 좋은 방법이 될 수 있지만 어떻게 든 Intl.NumberFormat.format()API 만으로 사양을 제공하고 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은 미국에서 1,234.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

The function has one weak point: It is not possible to guess the format if you have 1,123 or 1.123 - because depending on the locale format both might be a comma or a thousands-separator. In this special case the function will treat separator as a thousands-separator and return 1123.


It's baffling that they included a toLocaleString but not a parse method. At least toLocaleString without arguments is well supported in IE6+.

For a i18n solution, I came up with this:

First detect the user's locale decimal separator:

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

Then normalize the number if there's more than one decimal separator in the String:

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

Finally, remove anything that is not a number or a decimal separator:

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

This is a simplistic unobtrusive wrapper around the parseFloat function.

function parseLocaleNumber(str) {
  // Detect the user's locale decimal separator:
  var decimalSeparator = (1.1).toLocaleString().substring(1, 2);
  // Detect the user's 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);
}

If you want to avoid the problem that David Meister posted and you are sure about the number of decimal places, you can replace all dots and commas and divide by 100, ex.:

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

or if you have 3 decimals

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

It's up to you if you want to use parseInt, parseFloat or Number. Also If you want to keep the number of decimal places you can use the function .toFixed(...).


All of these answers fail if you have a number in the millions.

3,456,789 would simply return 3456 with the replace method.

The most correct answer for simply removing the commas would have to be.

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

Or simply written.

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

If you want a l10n answer do it this way. Example uses currency, but you don't need that. Intl library will need to be polyfilled if you have to support older browsers.

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, ""));

Replace the comma with an empty string:

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


If you have a small set of locales to support you'd probably be better off by just hardcoding a couple of simple rules:

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

참고URL : https://stackoverflow.com/questions/11665884/how-can-i-parse-a-string-with-a-comma-thousand-separator-to-a-number

반응형