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

2022-01-18 00:00:00 regex internationalization javascript

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

What is a good way for handling parameters in localized strings in javascript? I am using the same format as in java's MessageFormat class, e.g.:

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

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

Where {0} will be replaced with the first parameter and {1} with the second.

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

This is the call I want to use in JS (i.e. I want to implement origStr):

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

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

I am guessing the best strategy would be to use a regular expression. If so, please offer a good regular expression. But I'm open to hear any other options.

推荐答案

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-fying(不管它叫什么):

You can add fancy i18n features such as ordinal-i-fying (whatever it's called):

// Not well tested.

i18n.en.filters = {
    ordinal: function(n) {
        // FIXME Doesn't handle all cases.
        switch(('' + n).substr(-1)) {
            case '1':
                return '' + n + 'st';
            case '2':
                return '' + n + 'nd';
            case '3':
                return '' + n + 'rd';
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case '0':
                return '' + n + 'th';
            default:
                return n; // Just in case...
        }

    },
    plural: function(n, singular, plural) {
        if(n == 1) {
            return singular;
        } else {
            return plural;
        }
    }
};

i18n.current = i18n.en;

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

    return this.replace(/{((d+)((|w+(:w+)*)*))}/g, function() {
        var arg = args[arguments[2]],
            filters = arguments[3].split('|'),
            i, curFilter, curFilterArgs, curFilterFunc;

        for(i = 0; i < filters.length; ++i) {
            curFilterArgs = filters[i].split(':');
            curFilter = curFilterArgs.shift();
            curFilterFunc = i18n.current.filters[curFilter];

            if(typeof curFilterFunc === 'function') {
                arg = curFilterFunc.apply(null, [ arg ].concat(curFilterArgs));
            }
        }

        return arg;
    });
};

'You have {0} {0|plural:cow:cows} but I have {1} {1|plural:cow:cows}.'.format(2,1);
'My horse came in {0|ordinal} place while yours came in {1|ordinal}.'.format(42,1);

相关文章