2010-11-25 4 views
2

J'essaie d'imiter le fonctionnement d'un clavier international. Si vous utilisez l'un des dead keys suivi d'une lettre, il les combine dans le caractère correspondant. Par exemple, en tapant `a entraînerait à et ^o résultats dans ô, etc.Remplacer les caractères pour faire des lettres internationales (signes diacritiques)

Je ne peux pas sembler obtenir mon regex fonctionne correctement (je suce à regex!), Mais c'est ce que j'ai à ce jour (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); 
} 

de plus, si vous connaissez une méthode plus efficace pour faire la même chose, j'ai l'amour de l'entendre!


J'ai mis à jour ma réponse ci-dessus avec le problème Aefxx trouvé - merci! Mais j'ai décidé d'aller avec la méthode de Kenny car elle est plus propre, merci à tous! :) (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); 

Répondre

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

Merci ... J'ai pensé utiliser les accents comme clé, mais je pensais que l'objet serait plus grand que ce que j'avais déjà. Il s'avère que c'est plus propre :) – Mottie

0

Une regex doit-elle être utilisée? il semble plus facile de simplement parcourir toute la chaîne. Eh bien, ce serait comme l'automate de codage à la main à la place, mais en utilisant la table déjà définie par combos

1

Ok, problème résolu. Vous avez fait une erreur beaucoup d'utilisation (moi inclus) assez souvent. Appeler replace sur une chaîne sans affectation ne fonctionnera pas, vous remplacez simplement dans la nature.

... 
// 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

Merci c'était le problème! Mais je vais aller avec la réponse de Kenny car c'est beaucoup plus efficace. J'apprécie toujours l'aide! – Mottie

1

Une approche plus complète est le port JavaScript de l'algorithme de pliage ASCII Apache Lucene vous pouvez trouver à https://github.com/mplatt/fold-to-ascii-js Il gère les diacritiques dont vous avez parlé et bien d'autres personnages.

+0

+1 Ce sur quoi je travaillais fait l'inverse - saisissez '^ o' et obtenez' ô'; mais c'est quand même très beau travail! Je vais chercher à l'inclure avec mon [projet tablesorter] (http://mottie.github.io/tablesorter/docs/#sortlocalecompare);) – Mottie

+0

@Mottie Merci! Je ne peux pas prendre le crédit cependant. Tous les "gros travaux" en termes de création de la table de remplacement ont été réalisés par les développeurs d'Apache Lucene. Tout ce que j'ai fait était de le porter à JS. –

Questions connexes