2010-11-25 78 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