如何根据语言环境将字符串转换为数字(与.toLocaleString相反)?

69

如果我这样做:

var number = 3500;
alert(number.toLocaleString("hi-IN"));

我会获得印地语中的३,५००

但是我该如何将它转换回3500呢? 我想要这样的结果:

var str='३,५००';
alert(str.toLocaleNumber("en-US"));

所以,它可以给出3500

用JavaScript或jQuery是否可能?


3500以'en-Us'格式的结果将是3,500。 - Reporter
2
数字只是数字,所以没有“en-US”数字。真正的问题是如何解析来自不同语言环境的字符串。因此,需要类似于parseIntFromLocale这样的函数。有很多数字格式化和解析库可供选择,我相信其中一个一定支持印地语。我认为JavaScript本身没有这方面的本地化支持。 - Matt Burland
它不考虑千位分隔符和小数点,但可以查看JavaScript无法将印地语/阿拉伯语数字转换为实际数字变量 - Bergi
2
我以前用过这个jQuery插件 jquery.numberformatter,它声称支持 in 区域设置(但我从未尝试过)。它可以让你做像这样的事情:$.parseNumber(str, {format:"#,###", locale:"in"}); - Matt Burland
1
$.parseNumber(str, {format:"#,###", locale:"in"}); 对于 '३,५००' 没有起作用。 - user2754545
显示剩余2条评论
7个回答

6

Globalize很棒,是完成这个任务的最佳方式。参见此处的示例用法 - Codebling

2

使用Globalize库

安装它

npm install globalize cldr-data --save

然后

var cldr = require("cldr-data");
var Globalize = require("globalize");

Globalize.load(cldr("supplemental/likelySubtags"));
Globalize.load(cldr("supplemental/numberingSystems"));
Globalize.load(cldr("supplemental/currencyData"));

//replace 'hi' with appropriate language tag
Globalize.load(cldr("main/hi/numbers"));
Globalize.load(cldr("main/hi/currencies"));

//You may replace the above locale-specific loads with the following line,
// which will load every type of CLDR language data for every available locale
// and may consume several hundred megs of memory!
//Use with caution.
//Globalize.load(cldr.all());

//Set the locale
//We use the extention u-nu-native to indicate that Devanagari and
// not Latin numerals should be used.
// '-u' means extension
// '-nu' means number
// '-native' means use native script
//Without -u-nu-native this example will not work
//See 
// https://en.wikipedia.org/wiki/IETF_language_tag#Extension_U_.28Unicode_Locale.29
// for more details on the U language code extension 
var hindiGlobalizer = Globalize('hi-IN-u-nu-native');

var parseHindiNumber = hindiGlobalizer.numberParser();
var formatHindiNumber = hindiGlobalizer.numberFormatter();
var formatRupeeCurrency = hindiGlobalizer.currencyFormatter("INR");

console.log(parseHindiNumber('३,५००')); //3500
console.log(formatHindiNumber(3500));   //३,५००
console.log(formatRupeeCurrency(3500)); //₹३,५००.००

https://github.com/codebling/globalize-example


与此最佳答案完全相同,该答案是在此之前2年发布的。 - vsync
2
@vsync 有点道理,它确实涉及到相同的库,但是我的回答提供了问题的解决方案,而排名第一的答案只提供了两个“可能会有帮助”的链接。虽然我已经给他的回答点赞了,但它真的不比“这里有一个可能有用的资源”的建议更好。我认为仅有链接的答案通常不被认为是可接受的,但你拥有所有声望。人们可以争论说我应该将我的答案添加到第一个答案中,但我们都只是为了神奇的网络点数在这里吧? - Codebling

2

最近,我一直在苦恼如何将以任何语言环境格式化的字符串数字转换回数字。

我受到了 NG Prime InputNumber 组件实现的启发。他们使用了 Intl.NumberFormat.prototype.format()(我推荐使用)将值格式化为区域字符串,并基于简单示例创建了一组 RegExp 表达式,以便从格式化的字符串中分离出特定表达式。

使用 Intl.Numberformat.prototype.formatToParts() 可以简化此解决方案。该方法返回关于用于特定区域设置中格式化您的值所使用的所有分组/小数点/货币和其他分隔符的信息,因此您可以轻松地清除它们以前格式化的字符串。它似乎是最简单的解决方案,可涵盖所有情况,但是您必须知道先前格式化该值的区域设置。

为什么 Ng Prime 没有采用这种方式呢?我认为这是因为 Intl.Numberformat.prototype.formatToParts() 不支持 IE11,或者可能还有其他我没有注意到的原因。

使用此解决方案的完整代码示例可以在 此处 找到。


我本来想把这个作为答案写出来,因为我最近也遇到了这个问题。但是我决定在这里添加一个完整的代码示例链接。 - Pete

1

很遗憾,您必须手动处理本地化。受this answer的启发,我创建了一个函数,将手动替换印度数字:

function parseHindi(str) {
    return Number(str.replace(/[०१२३४५६७८९]/g, function (d) {
        return d.charCodeAt(0) - 2406;
    }).replace(/[०१२३४५६७८९]/g, function (d) {
        return d.charCodeAt(0) - 2415;
    }));
}

alert(parseHindi("३५००"));

在这里查看代码示例: http://jsfiddle.net/yyxgxav4/


非常感谢。但是我现在处于这样一种情况:我必须将任何语言的数字转换为英文,因为我的应用程序必须支持所有可能的文化。 - user2754545
1
你将不得不逐个处理那些带有非拉丁字符的语言。我曾经参与过许多本地化项目,但不幸的是,并不存在所谓的“通用翻译器”。 - o--oOoOoO--o

1
这个问题的一个常见场景是将浮点数显示给用户,然后希望以数字值的形式返回它。
在这种情况下,JavaScript 首先拥有该数字,但在将其格式化为显示时会失去它。解析的一个简单解决方法是存储真实的浮点值以及格式化后的值:
var number = 3500;
div.innerHTML = number.toLocaleString("hi-IN");
div.dataset.value = number;

然后通过解析数据属性将其取回:

var number = parseFloat(div.dataset.value);

这是哥伦布蛋式的答案。只要问题是一个蛋,它就能起作用。


0

你可以试一下

function ConvertDigits(input, source, target) {
var systems = {
    arabic: 48, english: 48, tamil: 3046, kannada: 3302, telugu: 3174, hindi: 2406,
    malayalam: 3430, oriya: 2918, gurmukhi: 2662, nagari: 2534, gujarati: 2790,
},
output = [], offset = 0, zero = 0, nine = 0, char = 0;
source = source.toLowerCase();
target = target.toLowerCase();

if (!(source in systems && target in systems) || input == null || typeof input == "undefined" || typeof input == "object") {
    return input;
}

input = input.toString();
offset = systems[target] - systems[source];
zero = systems[source];
nine = systems[source] + 9;    
for (var i = 0 ; i < input.length; i++) {
    var char = input.charCodeAt(i);
    if (char >= zero && char <= nine) {
        output.push(String.fromCharCode(char + offset));
    } else {
        output.push(input[i]);
    }
}
return output.join("");

}

var res = ConvertDigits('१२३४५६७८९', 'hindi', 'english');

我从这里得到了它。 如果你需要一个jquery的东西,那么请尝试这个链接


1
我认为这个处理方式并没有考虑到各种与地区相关的千位分隔符或十万/亿位分隔符,而这在 toLocaleString 的结果中比不同数字字符更常见。 - hippietrail

-1
var number = 3500;

var toLocaleString = number.toLocaleString("hi-IN")

var formatted = toLocaleString.replace(',','')

var converted = parseInt(formatted)

1
感谢您提供的这段代码片段,它可能会提供一些有限的、即时的帮助。通过说明为什么这是一个好的解决方案,一个适当的解释将极大地提高其长期价值,并使其对未来读者的其他类似问题更有用。请编辑您的答案,添加一些说明,包括您所做的假设。 - CertainPerformance
这与所请求的问题相反。该问题要求如何将本地化字符串转换为数字,而不是将数字转换为本地化字符串。 - Fydo
这在使用逗号作为小数分隔符的地区,如德国和许多其他欧洲地区是不适用的。请参考https://en.wikipedia.org/wiki/Decimal_separator#Countries_using_decimal_comma。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接