替换字符以制作国际字母(变音符号)

时间:2010-11-25 08:37:01

标签: javascript regex

我试图模仿国际键盘的工作方式。如果您使用dead keys之一后跟一个字母,它会将它们组合成相应的字符。例如,输入`a会导致à^o结果为ô等。

我似乎无法使我的正则表达式正常工作(我吮吸正则表达式!),但这是我到目前为止(demo):

var txt = "Replacing 'a ^u ~n 'e ^I 'c",

    combos = {
        'a': ['à', 'á', 'ä', 'â'],
        'A': ['À', 'Á', 'Ä', 'Â'],
        'e': ['è', 'é', 'ë', 'ê'],
        'E': ['È', 'É', 'Ë', 'Ê'],
        'i': ['ì', 'í', 'ï', 'î'],
        'I': ['Ì', 'Í', 'Ï', 'Î'],
        'o': ['ò', 'ó', 'ö', 'ô'],
        'O': ['Ò', 'Ó', 'Ö', 'Ô'],
        'u': ['ù', 'ú', 'ü', 'û'],
        'U': ['Ù', 'Ú', 'Ü', 'Û'],
        'y': 'ý',
        'Y': 'Ý',
        'c': 'ç',
        'C': 'Ç',
        'n': 'ñ',
        'N': 'Ñ'
    },

    bslash = /`[(aeiou)]/gi,
    fslash = /\'[(aeiouyc)]/gi,
    ddots = /\"[(aeiou)]/gi,
    caret = /\^[(aeiou)]/gi,
    tidle = /~[(n)]/gi;

// global match
if (txt.match(/[`|\'|\"|\^|~][aeiouycn]/i)) {

    // back slash - replace `a with à
    if (bslash.test(txt)) {
        txt = txt.replace(bslash, function(r) {
            // r contains the `, so remove it with a slice
            return combos[r.slice(-1)][0];
        });
    }

    // forward slash - replace 'a with á, etc
    if (fslash.test(txt)) {
        txt = txt.replace(fslash, function(r) {
            r = r.slice(-1);
            return (r == 'c' || r == 'y') ? combos[r][0] : combos[r][3];
        });
    }

    // double dots - replace `a with à
    if (ddots.test(txt)) {
        txt = txt.replace(ddots, function(r) {
            return combos[r.slice(-1)][4];
        });
    }

    // caret - replace ^a with â
    if (caret.test(txt)) {
        txt = txt.replace(caret, function(r) {
            return combos[r.slice(-1)][3];
        });
    }

    // tidle - replace ~n with ñ
    if (tidle.test(txt)) {
        txt = txt.replace(tidle, function(r) {
            return combos[r.slice(-1)][0];
        });
    }

    document.write(txt);
}

另外,如果你知道一种更有效的方法来做同样的事情,我很乐意听到它!


我用Aefxx发现的问题更新了上面的答案 - 谢谢!但我决定采用Kenny的方法,因为它更干净,谢谢大家! :)(updated demo

var txt = "Replacing 'a ^u ~n 'e ^I 'c",

 combos = {
  '`' :{ a:'à', A:'À', e:'è', E:'È', i:'ì', I:'Ì', o:'ò', O:'Ò', u:'ù', U:'Ù' },
  "'" :{ a:'á', A:'Á', e:'é', E:'É', i:'í', I:'Í', o:'ó', O:'Ó', u:'ú', U:'Ú', y:'ý', Y:'Ý', c:'ç', C:'Ç' },
  '"' :{ a:'ä', A:'Ä', e:'ë', E:'Ë', i:'ï', I:'Ï', o:'ö', O:'Ö', u:'ü', U:'Ü' },
  '^' :{ a:'â', A:'Â', e:'ê', E:'Ê', i:'î', I:'Î', o:'ô', O:'Ô', u:'û', U:'Û' },
  '~' :{ n:'ñ', N:'Ñ' }
 };

 txt = txt.replace(/([`\'~\^\"])([a-z])/ig, function(s, accent, letter){
   return (accent in combos) ? combos[accent][letter] || s : s;
 });

 document.write(txt);

4 个答案:

答案 0 :(得分:1)

var txt = "Replacing 'a ^u ~n 'e ^I 'c";

var combos = {
   '^': {a: 'â', A: 'Â', e: 'ê', E: 'Ê', ...},
   "'": {a: 'á', ...},
   ...
};

return txt.replace(/([`'~^"])([a-z])/ig, function(s, accent, letter){
  if (accent in combos) {
    return combos[accent][letter] || s;
  }
  return s;
}

答案 1 :(得分:1)

好的,问题解决了。你经常犯了很多错误(包括我)的错误。在没有分配的情况下对字符串调用replace将不起作用,您只是替换为狂野。

...
// Notice the assignment of the replaced text here !!!
txt = txt.replace(bslash, function(r) {
        // r contains the `, so remove it with a slice
        return combos[r.slice(-1)][0];
    });

答案 2 :(得分:1)

更完整的方法是您可以在https://github.com/mplatt/fold-to-ascii-js找到的Apache Lucene ASCII折叠算法的JavaScript端口 它处理你提到的变音符号和更多的字符。

答案 3 :(得分:0)

必须使用正则表达式吗?通过整个字符串似乎更容易。好吧,这就像用手编码自动机一样,但是使用已经由combos定义的表