javascript中的MessageFormat(本地化UI字符串中的参数)

javascript中的MessageFormat(本地化UI字符串中的参数),javascript,regex,internationalization,Javascript,Regex,Internationalization,在javascript中处理本地化字符串中的参数的好方法是什么? 我使用的格式与java的MessageFormat类中的格式相同,例如: 篮子ID{1}中有{0}个苹果。 其中,{0}将替换为第一个参数,{1}将替换为第二个参数 这是我想在JS中使用的调用(即我想实现origStr): var str=replaceParams(origStr[5,'AAA']) 我猜最好的策略是使用正则表达式。如果是,请提供一个好的正则表达式。但我愿意听取任何其他选择 String.prototype.fo

在javascript中处理本地化字符串中的参数的好方法是什么? 我使用的格式与java的MessageFormat类中的格式相同,例如:

篮子ID{1}中有{0}个苹果。

其中,
{0}
将替换为第一个参数,
{1}
将替换为第二个参数

这是我想在JS中使用的调用(即我想实现
origStr
):

var str=replaceParams(origStr[5,'AAA'])

我猜最好的策略是使用正则表达式。如果是,请提供一个好的正则表达式。但我愿意听取任何其他选择

String.prototype.format = function() {
    var args = arguments;

    return this.replace(/\{(\d+)\}/g, function() {
        return args[arguments[1]];
    });
};

// Returns '2 + -1 = 1'.
'{0} + {1} = {2}'.format(2, -1, 1);
或符合您的要求:

function replaceParams(string, replacements) {
    return string.replace(/\{(\d+)\}/g, function() {
        return replacements[arguments[1]];
    });

    // Or, if prototype code above...
    String.format.apply(string, replacements);
}
您可以添加新奇的i18n功能,如ordinal-i-fiting(无论它叫什么):

//没有经过很好的测试。
i18n.en.过滤器={
序数:函数(n){
//FIXME不能处理所有的案件。
开关((''+n).substr(-1)){
案例“1”:
返回'+n+'st';
案例“2”:
返回'+n+'nd';
案例“3”:
返回'+n+'rd';
案例“4”:
案例“5”:
案例“6”:
案例“7”:
案例“8”:
案例“9”:
案例“0”:
返回'+n+'th';
违约:
返回n;//以防万一。。。
}
},
复数:函数(n,单数,复数){
如果(n==1){
返回单数;
}否则{
返回复数;
}
}
};
i18n.电流=i18n.en;
String.prototype.format=函数(){
var args=参数;
返回此。替换(/\{((\d+)(\\\\w+(:\w+*)*)\}/g,函数(){
var arg=args[参数[2]],
筛选器=参数[3]。拆分(“|”),
i、 curFilter、curFilterArgs、curFilterFunc;
对于(i=0;i
看起来我只晚了3年左右,但万一有人还需要一个真正独立的JS MessageFormat库:

好了!编译为JS-因此速度非常快,并且支持
SelectFormat
PluralFormat


注意:这是ICU消息格式,与您的语言中可能内置的内容有点不同(阅读:更好)。

@strager的答案对我来说并不太合适,但经过一点调整,我得到了我想要的格式(这与@Omesh的目标非常相似)

请注意,args数组的索引值不同

它应该像@strager建议的那样命名:

'I like {0} and {1} but not {2}'.format('apples', 'oranges', 'kiwi');

显示了JS是多么不成熟:(不得不说,这与我预期的有点不同。我们在Java中使用ICU消息格式,它看起来更像{0,复数,零{no results}一个{1 result}另一个{0}results}。而这个看起来像{RES,复数,=0{no results}一个{1 result}另一个{results}-除了表面上对一个/另一个/等使用相同的CLDR关键字之外,对我来说,这似乎是一种完全不同的格式。MessageFormat.js和MessageFormat.java只是碰巧共享名称。语法完全不同。它们是相同的格式,并且实际上大部分是相互兼容的。上面提到了@Trejkaz的两个示例在使用的关键字方面有很大的不同。
=0
是一个文字值,其中
0
是一个关键字(不适用于en-US)。“不适用”,但就我们所知,它可以完全正常工作,并且在谈论“无事”时有助于区分消息。
String.prototype.format = function() {
    var args = arguments;

    return this.replace(/\{(\d+)\}/g, function(a) {
        return args[0][parseInt(a.match(/(\d+)/g))];
    });
};
'I like {0} and {1} but not {2}'.format('apples', 'oranges', 'kiwi');