ฉันมี2,299.00
เป็นสตริงและฉันพยายามแยกวิเคราะห์เป็นตัวเลข ฉันลองใช้parseFloat
ซึ่งผลลัพธ์เป็น 2 ฉันเดาว่าลูกน้ำคือปัญหา แต่ฉันจะแก้ปัญหานี้อย่างไรให้ถูกต้อง เพียงแค่ลบลูกน้ำ?
var x = parseFloat("2,299.00")
alert(x);
ฉันมี2,299.00
เป็นสตริงและฉันพยายามแยกวิเคราะห์เป็นตัวเลข ฉันลองใช้parseFloat
ซึ่งผลลัพธ์เป็น 2 ฉันเดาว่าลูกน้ำคือปัญหา แต่ฉันจะแก้ปัญหานี้อย่างไรให้ถูกต้อง เพียงแค่ลบลูกน้ำ?
var x = parseFloat("2,299.00")
alert(x);
คำตอบ:
ใช่ลบเครื่องหมายจุลภาค:
parseFloat(yournumber.replace(/,/g, ''));
.replace(/,/g, '')
regex นี้ใช้ global g
เพื่อแทนที่ทั้งหมด
parseFloat("2,000,000.00".replace(',',''))
ผลตอบแทน2000
และ 2. มันล้มเหลวในหลายภูมิภาคของโลกที่,
มีตำแหน่งทศนิยมเช่นparseFloat("2.000.000,00".replace(',',''))
ผลตอบแทน2
- ดูคำตอบของฉันด้านล่างสำหรับสิ่งที่ใช้ได้ทุกที่ในโลก
การลบเครื่องหมายจุลภาคอาจเป็นอันตรายได้เนื่องจากตามที่คนอื่น ๆ ได้กล่าวไว้ในความคิดเห็นหลายภาษาใช้เครื่องหมายจุลภาคเพื่อหมายถึงสิ่งที่แตกต่างกัน (เช่นตำแหน่งทศนิยม)
ฉันไม่รู้ว่าคุณเอาสายอักขระมาจากไหน แต่ในบางที่ในโลก"2,299.00"
=2.299
Intl
วัตถุที่จะได้รับเป็นวิธีที่ดีที่จะจัดการปัญหานี้ แต่อย่างใดพวกเขาก็พยายามที่จะจัดส่งข้อมูลจำเพาะมีเพียงIntl.NumberFormat.format()
API และไม่มีparse
คู่ :(
วิธีเดียวในการแยกวิเคราะห์สตริงที่มีอักขระตัวเลขทางวัฒนธรรมไปยังหมายเลขที่เครื่องจดจำได้ด้วยวิธีที่มีเหตุผลของ i18n คือการใช้ไลบรารีที่ใช้ประโยชน์จากข้อมูล CLDR เพื่อปกปิดวิธีที่เป็นไปได้ทั้งหมดในการจัดรูปแบบสตริงตัวเลขhttp: //cldr.unicode องค์กร /
ตัวเลือก JS ที่ดีที่สุดสองตัวที่ฉันเจอมาจนถึงตอนนี้:
ในเบราว์เซอร์ที่ทันสมัยคุณสามารถใช้Intl.NumberFormatในตัวเพื่อตรวจจับการจัดรูปแบบหมายเลขของเบราว์เซอร์และปรับอินพุตให้เป็นปกติ
function parseNumber(value, locales = navigator.languages) {
const example = Intl.NumberFormat(locales).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 }`);
}
เห็นได้ชัดว่ามีห้องสำหรับการเพิ่มประสิทธิภาพและการแคช แต่ก็ใช้ได้ผลในทุกภาษา
const cleanPattern = new RegExp("[^-+0-9" + example.charAt( 1 ) + "]", 'g');
- template strings "` "ไม่รองรับโดย IE - caniuse.com/#search=template%20string
navigator.languages
แทนการnavigator.language
ที่จะสร้าง? ฉันสงสัยว่าเพราะในหนังสือ "JavaScript สมัยใหม่สำหรับคนใจร้อน" หน้า 180 แนะนำให้ใช้อันนั้น ไม่แน่ใจว่าความแตกต่างคืออะไร
ลบสิ่งที่ไม่ใช่ตัวเลขจุดทศนิยมหรือเครื่องหมายลบ ( -
):
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, "");
str = str.replace(/(\d+),(?=\d{3}(\D|$))/g, "$1");
นี่คือสิ่งที่ฉันจะใช้ แต่ฉันใช้ regex อย่างไร้ประโยชน์และเป็นสิ่งที่ฉันพบในขณะที่กลับมาในเธรด SO อื่น ๆ
parseFloat
- ซึ่งจะตรวจสอบความถูกต้อง :-)
โดยปกติคุณควรพิจารณาใช้ช่องป้อนข้อมูลซึ่งไม่อนุญาตให้ป้อนข้อความฟรีสำหรับค่าตัวเลข แต่อาจมีบางกรณีที่คุณต้องเดารูปแบบการป้อนข้อมูล ตัวอย่างเช่น 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
3,00 €
ยังถูกแทนที่เป็น 3.00 เพียงแค่ทราบว่ามีการจัดรูปแบบให้3,001
3001
เพื่อหลีกเลี่ยงปัญหานี้อินพุตควรเป็นสัญลักษณ์ทศนิยมเสมอ เช่น3,001.00€
3,001.00
แปลงอย่างถูกต้อง นอกจากนี้โปรดอัปเดต jsfiddle 0,124
ยังคงแปลงเป็น 124
มันน่างงที่พวกเขารวมtoLocaleStringแต่ไม่ใช่วิธีการแยกวิเคราะห์ อย่างน้อย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, "."));
นี่คือกระดาษห่อหุ้มที่เรียบง่ายไม่สร้างความรำคาญรอบ ๆ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);
}
หากคุณต้องการหลีกเลี่ยงปัญหาที่ David Meister โพสต์และคุณแน่ใจเกี่ยวกับจำนวนตำแหน่งทศนิยมคุณสามารถแทนที่จุดและลูกน้ำทั้งหมดแล้วหารด้วย 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(''));
สิ่งนี้จะแปลงตัวเลขในภาษาใดก็ได้ให้เป็นตัวเลขปกติ ใช้ได้กับจุดทศนิยมเช่นกัน:
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
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, '.'));
};
ด้วยฟังก์ชันนี้คุณจะสามารถจัดรูปแบบค่าในหลายรูปแบบเช่น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"
หากคุณต้องการคำตอบ l10n ให้ทำด้วยวิธีนี้ ตัวอย่างใช้สกุลเงิน แต่คุณไม่ต้องการสิ่งนั้น ห้องสมุดนานาชาติจะต้องได้รับการเติมเต็มหากคุณต้องรองรับเบราว์เซอร์รุ่นเก่า
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()
แทนที่เฉพาะการจับคู่แรกเมื่อไม่ได้ใช้RegExp
กับ'g'
ธง
,
ซึ่งอยู่ในตัวคั่นด้วยเครื่องหมายจุลภาคในบางภาษา
แทนที่เครื่องหมายจุลภาคด้วยสตริงว่าง:
var x = parseFloat("2,299.00".replace(",",""))
alert(x);
หากคุณมีสถานที่ตั้งเล็ก ๆ เพื่อรองรับคุณอาจจะดีกว่าโดยการเข้ารหัสกฎง่ายๆสองสามข้อ:
function parseNumber(str, locale) {
let radix = ',';
if (locale.match(/(en|th)([-_].+)?/)) {
radix = '.';
}
return Number(str
.replace(new RegExp('[^\\d\\' + radix + ']', 'g'), '')
.replace(radix, '.'));
}
Number("2,299.00".split(',').join('')); // 2299
ฟังก์ชันแยกจะแยกสตริงออกเป็นอาร์เรย์โดยใช้ "," เป็นตัวคั่นและส่งกลับอาร์เรย์
ฟังก์ชัน join จะรวมองค์ประกอบของอาร์เรย์ที่ส่งคืนจากฟังก์ชันแยก
ฟังก์ชัน Number () แปลงสตริงที่รวมเป็นตัวเลข