私は持っています 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/
これまでにこれまで出会った2つの最良の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を意味します。 10進数としてコンマを使用する国のリストについては、 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つの弱点があります。1,123または1.123がある場合、形式を推測することはできません。ロケール形式によっては、両方がコンマまたは3桁区切り文字になる可能性があるためです。この特別な場合、関数はセパレータを千単位のセパレータとして扱い、1123を返します。
toLocaleStringメソッドが含まれていたがparseメソッドが含まれていなかったのは不可解です。 IE6 +では、少なくともtoLocaleString引数なしがサポートされています。
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, "."));
デビッドマイスターが投稿した問題を避けたい場合、小数点以下の桁数が確かな場合は、すべてのドットとコンマを置き換えて、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(...)を使用できます。
これは、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);
}
数百万の数がある場合、これらの答えはすべて失敗します。
3,456,789は、replaceメソッドで単に3456を返します。
カンマを単に削除するための最も正しい答えは、そうでなければならないでしょう。
var number = '3,456,789.12';
number.split(',').join('');
/* number now equips 3456789.12 */
parseFloat(number);
または単に書かれた。
number = parseFloat(number.split(',').join(''));
カンマを空の文字列に置き換えます。
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, '.'));
}
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, ""));