2010-11-25 79 views
2

我试图仿效国际键盘的工作方式。如果您使用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找到的答案 - 谢谢!但我决定采用肯尼的方法,因为它更干净,谢谢大家! :)(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); 

回答

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; 
} 
+0

谢谢......我想过使用重音作为关键,但我认为这个物体会比我已经拥有的更大。原来它更干净:) – Mottie 2010-11-25 10:01:23

0

必须使用正则表达式吗?穿过整个字符串似乎更容易。那么,这将像手动代码自动机,而是使用已定义的表combos

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]; 
    }); 
+0

谢谢你是这个问题!但是我要去肯尼的答案,因为它更有效率。我仍然感谢帮助! – Mottie 2010-11-25 10:00:21

1

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

+0

+1我正在做的是做相反的事情 - 在`^ o`中输入'?';但这仍然是非常好的工作!我会考虑包括它与我的[tablesorter项目](http://mottie.github.io/tablesorter/docs/#sortlocalecompare);) – Mottie 2014-01-08 00:17:28