[javascript] 쉼표로 구분 된 문자열을 숫자로 구문 분석하려면 어떻게해야합니까?

나는 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

이 함수에는 한 가지 약점이 있습니다. 1,123 또는 1.123이있는 경우 형식을 추측 할 수 없습니다. 로캘 형식에 따라 둘 다 쉼표 또는 천 단위 구분 기호 일 수 있기 때문입니다. 이 특별한 경우 함수는 구분 기호를 천 단위 구분 기호로 처리하고 1123을 반환합니다.


답변

toLocaleString이 포함되어 있지만 구문 분석 방법이 없다는 것은 당혹 스럽습니다 . 적어도 toLocaleString인수가없는 은 IE6 +에서 잘 지원됩니다.

A의 국제화의 솔루션, 나는이 함께했다 :

먼저 사용자의 로케일 소수 구분 기호를 감지하십시오.

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

그런 다음 문자열에 소수점 구분 기호가 두 개 이상 있으면 숫자를 정규화합니다.

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'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);
}