代码之家  ›  专栏  ›  技术社区  ›  Mottie

替换字符以生成国际字母(变音符号)

  •  2
  • Mottie  · 技术社区  · 15 年前

    我想模仿国际键盘的工作方式。如果你使用 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);
    }
    

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


    我用找到的问题更新了上面的答案-谢谢!但我决定采用肯尼的方法,因为它更干净,谢谢大家!:) ( 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 回复  |  直到 15 年前
        1
  •  1
  •   kennytm    15 年前
    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;
    }
    
        2
  •  2
  •   mritz_p    12 年前

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

        3
  •  1
  •   aefxx    15 年前

    好的,问题解决了。你犯了一个错误,很多人(包括我)经常犯这个错误。打电话 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];
        });
    
        4
  •  0
  •   lijie    15 年前

    必须使用正则表达式吗?穿过整根绳子似乎更容易。好吧,这就像是手工编写自动机,但是使用已经由 combos