मैं एक नंबर पर अल्पविराम हजार विभाजक के साथ एक स्ट्रिंग को कैसे पार्स कर सकता हूं?


104

मेरे पास 2,299.00एक स्ट्रिंग है और मैं इसे एक नंबर पर पार्स करने की कोशिश कर रहा हूं। मैंने प्रयोग करने की कोशिश की parseFloat, जिसका परिणाम 2. मुझे लगता है कि कॉमा समस्या है, लेकिन मैं इस मुद्दे को सही तरीके से कैसे हल करूंगा? बस अल्पविराम हटा दें?

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

जवाबों:


121

हाँ अल्पविराम निकालें:

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

7
हाँ, लेकिन अब दशमलव स्थान खो गए हैं। उदाहरण के लिए 2300 में 2300.00 परिणाम।
user1540714

@ user1540714 यह एक स्ट्रिंग के बजाय एक फ्लोट है क्योंकि thats। यदि आपको इसके उत्पादन की आवश्यकता है तो आपको इसे हमेशा 2 दशमलव बिंदुओं को दिखाने के लिए प्रारूपित करने की आवश्यकता है।
जॉन टेलर

क्या इससे बचा जा सकता है? बीमार कोशिश करते हैं
यूजर 1540714

38
क्या मैं सुझाव दूंगा कि हम इसके बजाय सभी अल्पविरामों का उपयोग करते हैं: .replace(/,/g, '') यह रेगेक्स gसभी को बदलने के लिए वैश्विक उपयोग करता है ।
gdibble

32
मुझे पता नहीं है कि इस उत्तर को इतने सारे उत्थान क्यों मिले और इसे सही के रूप में चुना गया, इसके दो गंभीर मुद्दे हैं। 1. यह कई कॉमा के साथ संख्याओं को नहीं संभाल सकता है, जैसे parseFloat("2,000,000.00".replace(',',''))रिटर्न 2000और 2. यह दुनिया के कई क्षेत्रों में विफल रहता है जहां ,एक दशमलव स्थान है, जैसे parseFloat("2.000.000,00".replace(',',''))रिटर्न 2- दुनिया में हर जगह काम करने वाली किसी चीज के लिए मेरा जवाब नीचे देखें।
डेविड मिस्टर

113

कॉमा को हटाना संभावित रूप से खतरनाक है, क्योंकि जैसा कि दूसरों ने टिप्पणियों में उल्लेख किया है, बहुत से स्थान कॉमा का उपयोग कुछ अलग करने के लिए करते हैं (जैसे एक दशमलव)।

मुझे नहीं पता कि आपको अपनी स्ट्रिंग कहां से मिली, लेकिन दुनिया में कुछ जगहों पर "2,299.00"=2.299

Intlवस्तु इस समस्या से निपटने के लिए एक अच्छा तरीका हो सकता था, लेकिन किसी भी तरह वे केवल एक साथ कल्पना जहाज करने में कामयाब रहे Intl.NumberFormat.format()एपीआई और कोई parseसमकक्ष :(

किसी भी i18n समझदार तरीके से एक मशीन पहचानने योग्य संख्या के लिए इसमें सांस्कृतिक संख्यात्मक पात्रों के साथ एक स्ट्रिंग पार्स करने का एकमात्र तरीका एक पुस्तकालय का उपयोग करना है जो संख्या स्ट्रिंग्स को पूरा करने के लिए CLDR डेटा का उपयोग करता है । org /

जेएस के दो सबसे अच्छे विकल्प जो मुझे अब तक मिले हैं:


4
अभी तक कोई भी इस उत्तर को नहीं देख सकता, यह इस पृष्ठ पर एकमात्र वास्तविक उत्तर है!
17

9
पूरी तरह से सहमत हैं कि Intl में एक पार्सिंग समकक्ष होना चाहिए था। यह स्पष्ट प्रतीत होता है कि लोगों को इसकी आवश्यकता होगी।
carlossless

ऐसा करने का यह एकमात्र व्यवस्थित तरीका है। एक regex फिट बैठता है सभी दृष्टिकोण के साथ यह हासिल नहीं कर सकता। विभिन्न भाषाओं में कमास और काल के अलग-अलग अर्थ होते हैं।
वाइल्डहैमर

38

आधुनिक ब्राउज़रों पर आप ब्राउज़र की संख्या स्वरूपण का पता लगाने और मिलान के लिए इनपुट को सामान्य बनाने के लिए 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 }`);
}

कुछ अनुकूलन और कैशिंग के लिए उनका स्पष्ट रूप से कमरा है लेकिन यह सभी भाषाओं में मज़बूती से काम करता है।


इसको उभार का भार क्यों नहीं मिला !!! यह अंतरराष्ट्रीय प्रारूपों में INPUT के लिए सबसे सुंदर समाधान है! धन्यवाद!!
कोपलाक

फ्रांस में मुद्रा 231 123 413,12
स्टैकडेव

26

कुछ भी निकालें जो एक अंक, दशमलव बिंदु या शून्य चिह्न नहीं है ( -):

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

4
यह वैज्ञानिक अंकन में ऋणात्मक संख्याओं या संख्याओं के लिए काम नहीं करेगा।
आदित एम शाह

1
str = str.replace(/(\d+),(?=\d{3}(\D|$))/g, "$1"); यह वही है जो मैं उपयोग करूंगा लेकिन मैं regex पर पूरी तरह से बेकार हूं और कुछ ऐसा है जो मैंने कुछ समय पहले कुछ अन्य SO थ्रेड पर पाया था।
जॉन टेलर

@JonTaylor: यहां लक्ष्य संख्या को मान्य नहीं करना था , बस इसके लिए काम करना था parseFloat- जो इसे मान्य करेगा। :-)
टीजे क्राउडर

जहां तक ​​मुझे पता है, जो मेरा करता है। मैं इसका उपयोग 1,234,567 आदि को 1234567 में बदलने के लिए करता हूं। जैसा कि मैंने कहा कि हालांकि मैं regex में पूरी तरह से बेकार हूं, इसलिए मैं अपने जीवन के लिए यह नहीं बता सकता कि यह वास्तव में क्या करता है।
जॉन टेलर

1
बुरा विचार "-" माइनस साइन को हटाने के लिए - पूरी तरह से अन्य नंबर प्राप्त करें, और अगर आप विषम स्वरूपों को पार्स करते हैं, तो "7.500"! == "7,500"
सर्ज

14

आमतौर पर आपको इनपुट फ़ील्ड का उपयोग करने पर विचार करना चाहिए जो संख्यात्मक मानों के लिए मुफ्त टेक्स्ट इनपुट की अनुमति नहीं देता है। लेकिन ऐसे मामले हो सकते हैं, जब आपको इनपुट प्रारूप का अनुमान लगाने की आवश्यकता होती है। उदाहरण के लिए जर्मनी में 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 लौटाएंगे।


यह १,१११.११ जैसे नंबरों के लिए विफल रहता है, जो स्पष्ट रूप से अंग्रेजी प्रारूप है, लेकिन ११११११ पर लौटाता है
श्री गोफरिटो

धन्यवाद, श्री गोफरिटो - मुझे खेद है - मैंने फ़ंक्शन को ठीक किया।
गेरफ्रीड

ऐसा लगता है कि उदाहरण के लिए फ्रेंच लोकेल में बहुत कम संख्या "0,124" के लिए भी विफल हो सकता है।
पॉल अलेक्जेंडर

तुम महान हो! यह लगभग वैसा ही है, जैसा मैं देख रहा था: इसे 3,00 €भी बदल कर 3.00 कर दिया गया है। बस एक नोट, जिसे 3,001स्वरूपित किया गया है 3001। इससे बचने के लिए, इनपुट हमेशा दशमलव प्रतीकों के साथ होना चाहिए। जैसे 3,001.00€ 3,001.00सही ढंग से धर्मान्तरित। इसके अलावा, कृपया, jsfiddle अपडेट करें। 0,124वहाँ अभी भी 124
अर्निस जुरगा

अच्छी तरह से किया गया दोस्त मुझे लगता है कि इसका सही जवाब है
वहीद

5

यह चकित करने वाला है कि उन्होंने एक टोलेस्ट्रीमिंग को शामिल किया, लेकिन एक पार्स विधि नहीं। कम से कम तर्क के बिना toLocaleString IE6 + में अच्छी तरह से समर्थित है।

एक i18n समाधान के लिए, मैं इसके साथ आया:

पहले उपयोगकर्ता के स्थानीय दशमलव विभाजक का पता लगाएं:

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

5

यह 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);
}

2

यदि आप उस समस्या से बचना चाहते हैं जिसे डेविड मिस्टर ने पोस्ट किया है और आप दशमलव स्थानों की संख्या के बारे में सुनिश्चित हैं, तो आप सभी डॉट्स और कॉमा को बदल सकते हैं और 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 या संख्या का उपयोग करना चाहते हैं तो यह आपके ऊपर है। इसके अलावा, यदि आप दशमलव स्थानों की संख्या रखना चाहते हैं, तो आप फ़ंक्शन का उपयोग कर सकते हैं .toFixed (...)।


1

यदि आपके पास लाखों में संख्या है, तो ये सभी उत्तर विफल हो जाते हैं।

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

बेशक, अमेरिकी का उपयोग अल्पविराम और नहीं डॉट। दोनों को संभालने का प्रयास करने के लिए एक राक्षसी बनाने की कोशिश करना मूर्खतापूर्ण होगा।
केस

2
लेकिन यूनिकोड द्वारा प्रदान की गई (मेरा जवाब देखें) के हिस्से के रूप में इस तरह की "राक्षसी" पहले से मौजूद है। मुझे यकीन है कि अगर आप अंतरराष्ट्रीय ग्राहकों के साथ एक कंपनी चलाते हैं तो आप इस बारे में कम मूर्खता महसूस करेंगे।
डेविड मिस्टर

1

यह किसी भी स्थान पर एक संख्या को सामान्य संख्या में परिवर्तित करता है। दशमलव बिंदुओं के लिए भी काम करता है:

function numberFromLocaleString(stringValue, locale){
    var parts = Number(1111.11).toLocaleString(locale).replace(/\d+/g,'').split('');
    if (stringValue === null)
        return null;
    if (parts.length==1) {
        parts.unshift('');
    }   
    return Number(String(stringValue).replace(new RegExp(parts[0].replace(/\s/g,' '),'g'), '').replace(parts[1],"."));
}
//Use default browser locale
numberFromLocaleString("1,223,333.567") //1223333.567

//Use specific locale
numberFromLocaleString("1 223 333,567", "ru") //1223333.567

1

इस समारोह के साथ आप जैसे कई प्रारूपों में मानों को स्वरूपित करने में सक्षम हो जाएगा 1.234,56और 1,234.56, और यहां तक कि के साथ की तरह त्रुटियों 1.234.56और1,234,56

/**
 * @param {string} value: value to convert
 * @param {bool} coerce: force float return or NaN
 */
function parseFloatFromString(value, coerce) {
    value = String(value).trim();

    if ('' === value) {
        return value;
    }

    // check if the string can be converted to float as-is
    var parsed = parseFloat(value);
    if (String(parsed) === value) {
        return fixDecimals(parsed, 2);
    }

    // replace arabic numbers by latin
    value = value
    // arabic
    .replace(/[\u0660-\u0669]/g, function(d) {
        return d.charCodeAt(0) - 1632;
    })

    // persian
    .replace(/[\u06F0-\u06F9]/g, function(d) {
        return d.charCodeAt(0) - 1776;
    });

    // remove all non-digit characters
    var split = value.split(/[^\dE-]+/);

    if (1 === split.length) {
        // there's no decimal part
        return fixDecimals(parseFloat(value), 2);
    }

    for (var i = 0; i < split.length; i++) {
        if ('' === split[i]) {
            return coerce ? fixDecimals(parseFloat(0), 2) : NaN;
        }
    }

    // use the last part as decimal
    var decimal = split.pop();

    // reconstruct the number using dot as decimal separator
    return fixDecimals(parseFloat(split.join('') +  '.' + decimal), 2);
}

function fixDecimals(num, precision) {
    return (Math.floor(num * 100) / 100).toFixed(precision);
}
parseFloatFromString('1.234,56')
"1234.56"
parseFloatFromString('1,234.56')
"1234.56"
parseFloatFromString('1.234.56')
"1234.56"
parseFloatFromString('1,234,56')
"1234.56"

0

यदि आप एक 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, ""));

9
यह वास्तव में l10n उत्तर नहीं है, क्योंकि कुछ स्थानों (जैसे DE) के लिए अल्पविराम दशमलव बिंदु है।
एंड्रियास

और ध्वज के साथ replace()उपयोग न करने पर केवल पहले मैच की जगह लेता है । RegExp'g'
binki

@ बिंकी धन्यवाद फिक्स्ड।
टोनी टॉपर

@ और यह l10n जवाब है। यदि आप एक और मुद्रा चाहते थे तो आप करेंसी का मूल्य बदलकर उन देशों को कर देंगे।
टोनी टॉपर

1
@TonyTopper इस तथ्य को परिवर्तित नहीं करता है कि हजारों विभाजक के लिए प्रतिस्थापित हार्डकोड है ,जो कुछ स्थानों पर अल्पविराम में है
Andreas

0

खाली स्ट्रिंग के साथ अल्पविराम बदलें:

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


यह सुरक्षित नहीं है। जैसा कि अन्य उत्तरों में उल्लेख किया गया है, दुनिया के कई हिस्सों में कॉमा एक दशमलव बिंदु का प्रतिनिधित्व करते हैं।
डेविड मीस्टर

1
इसके अलावा यह विधि 2,299,000.00 पर काम नहीं करेगी क्योंकि यह केवल पहली अल्पविराम की जगह लेगी
wizulus

0

यदि आपके पास समर्थन करने के लिए स्थानों का एक छोटा सा समूह है, तो आप शायद कुछ नियमों को सख्त करके ही बेहतर होंगे।

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

0
const parseLocaleNumber = strNum => {
    const decSep = (1.1).toLocaleString().substring(1, 2);
    const formatted = strNum
        .replace(new RegExp(`([${decSep}])(?=.*\\1)`, 'g'), '')
        .replace(new RegExp(`[^0-9${decSep}]`, 'g'), '');
    return Number(formatted.replace(decSep, '.'));
};

0
Number("2,299.00".split(',').join(''));   // 2299

विभाजन फ़ंक्शन स्ट्रिंग को एक विभाजक के रूप में "," का उपयोग करके एक सरणी में विभाजित करता है और एक सरणी देता है।
ज्वाइन फंक्शन स्प्लिट फंक्शन से लौटे हुए एरे के तत्वों से जुड़ता है।
संख्या () फ़ंक्शन सम्मिलित स्ट्रिंग को एक संख्या में परिवर्तित करता है।


कृपया थोड़ा और विस्तृत करें कि इसका क्या समाधान है और यह समस्या का हल कैसे करता है।
तारिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.