【问题标题】:multi-charsets replacements issue [duplicate]多字符集替换问题[重复]
【发布时间】:2013-06-12 13:39:10
【问题描述】:

我有一个将英文数字字符更改为波斯语的功能:

  function en2fa(str){
    string = str.replace('1', '۱');
    string = string.replace('2', '۲');
    string = string.replace('3', '۳');
    string = string.replace('4', '۴');
    string = string.replace('5', '۵');
    string = string.replace('6', '۶');
    string = string.replace('7', '۷');
    string = string.replace('8', '۸');
    string = string.replace('9', '۹');
    string = string.replace('0', '۰');

    return string;
  }

我想深入了解一下js会怎么做:

var a = '12345';
alert(en2fa(a.replace('1', '3')));

我给这个:

323455

为什么? js如何解析这段文字?

============

已编辑:我的功能代码有误。 en2fa() 已编辑。

【问题讨论】:

  • 你能告诉我们en2fa(..)的实现吗?您发布了fa2en(..)
  • 本题题目与内容完全无关。以后访问该站点时遇到相同问题的访问者将永远找不到此问题,而对缩进有疑问的访问者会看到此问题并浪费时间。
  • 请澄清en2fa的内容(你没有显示,只有fa2en

标签: javascript text replace


【解决方案1】:

根据您问题中的线索,您的问题在于您进行替换的方式。 你向我们展示了fa2en,我想你的en2fa 是相似的。然而,更好的工作实现如下:

  function en2fa (str) {
    return str.replace (/\d/g, function (d) {
      return '۰۱۲۳۴۵۶۷۸۹'.charAt (+d);
    });
  }

您的主要问题是@tom 在您的代码中描述的,使用字符串替换仅替换第一次出现。 @tom 的答案虽然它可能有效,但它不是标准的。要替换所有匹配项,您应该使用 regExp 替换为 g 修饰符。这也会显着缩短代码!

【讨论】:

  • +1 显然是最优雅的解决方案 - 可能也是最有效的解决方案。
  • @Sebas 有趣的是,使用对象而不是字符串会使性能翻倍:jsperf.com/persian-translation
  • @tom,酷!这就是为什么我坚持“可能” :-) 实际上正则表达式并不是最快的替换方法..
  • @Sebas 在 Chrome 正则表达式上确实比 for 循环慢得多,但在 Firefox 中则相反。很有趣。
  • @hbp 谢谢,但您的回答仅适用于 en2fa 数字。用其他字符替换任何字符不是流行的方式(我认为)。但是对于 en2fa 来说是完美的 :) 谢谢
【解决方案2】:

默认情况下,replace 仅替换第一个匹配项。要替换所有匹配项,请使用带有 g 标志的正则表达式:

function en2fa(str){
    string = string.replace(/1/g, '۱');
    string = string.replace(/2/g, '۲');
    // ...
    return string;
}

var a = '12345';
alert(en2fa(a.replace(/1/g, '3')));

您可以使用查找表使翻译更简洁:

var en2faDict = {};
var fa2enDict = {};
"۰۱۲۳۴۵۶۷۸۹".split('').forEach(function(fa, en) {
    en = "" + en;
    en2faDict[en] = fa;
    fa2enDict[fa] = en;
});

function translate(str, dict, pattern) {
    return str.replace(pattern, function(c) { return dict[c]; });
}

function fa2en(str) {
    return translate(str, fa2enDict, /[۰-۹]/g);
}

function en2fa(str) {
    return translate(str, en2faDict, /[0-9]/g);
}

这是一个在某些浏览器中可能更快的版本。它使用 for 循环和范围检查,这依赖于数字是连续的这一事实:

var en2faDict = {};
var fa2enDict = {};
"۰۱۲۳۴۵۶۷۸۹".split('').forEach(function(fa, en) {
    en = "" + en;
    en2faDict[en] = fa;
    fa2enDict[fa] = en;
});
en2faDict.low = '0'.charCodeAt(0);
en2faDict.high = '9'.charCodeAt(0);
fa2enDict.low = en2faDict['0'].charCodeAt(0);
fa2enDict.high = en2faDict['9'].charCodeAt(0);

function translate(str, dict) {
    var i, l = str.length, result = "";
    for (i = 0; i < l; i++) {
        if (str.charCodeAt(i) >= dict.low && str.charCodeAt(i) <= dict.high)
            result += dict[str[i]];
        else
            result += str[i];
    }
    return result;
}

function fa2en(str) {
    return translate(str, fa2enDict);
}

function en2fa(str) {
    return translate(str, en2faDict);
}

【讨论】:

  • MDN 说到要替换的第三个参数:A string specifying a combination of regular expression flags. The use of the flags parameter in the String.replace method is non-standard. Instead of using this parameter, use a RegExp object with the corresponding flags.@developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 谢谢@HBP。我会更新我的答案。
  • 实际上,直到我在 Chrome 上尝试了您的代码并且令我惊讶的是它按您所说的那样执行时,我才知道第三个参数。这让我急于找出原因;-)
猜你喜欢
  • 2017-12-22
  • 2020-10-12
  • 1970-01-01
  • 1970-01-01
  • 2021-05-21
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
相关资源
最近更新 更多