2010-04-16 6 views
5

J'aime remplacer un certain ensemble de caractères d'une chaîne avec un caractère de remplacement correspondant d'une manière efficace.Comment remplacer des caractères dans une chaîne java?

Par exemple:

String sourceCharacters = "šđćčŠĐĆČžŽ"; 
String targetCharacters = "sdccSDCCzZ"; 

String result = replaceChars("Gračišće", sourceCharacters , targetCharacters); 

Assert.equals(result,"Gracisce") == true; 

Est-ce qu'il ya beaucoup plus efficace que d'utiliser la méthode replaceAll de la classe String?

Ma première idée était:

final String s = "Gračišće"; 
String sourceCharacters = "šđćčŠĐĆČžŽ"; 
String targetCharacters = "sdccSDCCzZ"; 

// preparation 
final char[] sourceString = s.toCharArray(); 
final char result[] = new char[sourceString.length]; 
final char[] targetCharactersArray = targetCharacters.toCharArray(); 

// main work 
for(int i=0,l=sourceString.length;i<l;++i) 
{ 
    final int pos = sourceCharacters.indexOf(sourceString[i]); 
    result[i] = pos!=-1 ? targetCharactersArray[pos] : sourceString[i]; 
} 

// result 
String resultString = new String(result); 

Toutes les idées? Btw, les caractères UTF-8 causent le problème, avec US_ASCII cela fonctionne très bien.

Répondre

14

Vous pouvez utiliser java.text.Normalizer et un coup de regex pour se débarrasser de l'diacritics dont il existe beaucoup plus que vous avez recueillis jusqu'à.

Voici un SSCCE, copy'n'paste'n'run sur Java 6:

package com.stackoverflow.q2653739; 

import java.text.Normalizer; 
import java.text.Normalizer.Form; 

public class Test { 

    public static void main(String... args) { 
     System.out.println(removeDiacriticalMarks("Gračišće")); 
    } 

    public static String removeDiacriticalMarks(String string) { 
     return Normalizer.normalize(string, Form.NFD) 
      .replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); 
    } 
} 

Cela devrait donner

Gracisce

Au moins, il fait ici à Eclipse avec le caractère de la console codage défini sur UTF-8 (Fenêtre> Préférences> Général> Espace de travail> Encodage du fichier texte). Assurez-vous que la même chose est définie dans votre environnement.

Comme alternative, maintenir un Map<Character, Character>:

Map<Character, Character> charReplacementMap = new HashMap<Character, Character>(); 
charReplacementMap.put('š', 's'); 
charReplacementMap.put('đ', 'd'); 
// Put more here. 

String originalString = "Gračišće"; 
StringBuilder builder = new StringBuilder(); 

for (char currentChar : originalString.toCharArray()) { 
    Character replacementChar = charReplacementMap.get(currentChar); 
    builder.append(replacementChar != null ? replacementChar : currentChar); 
} 

String newString = builder.toString(); 
+0

avec cette solution je reçois: GraA? IA¡Ae. et btw, je voudrais remplacer non seulement les caractères diacritiques mais d'autres d'autres langues aussi. donc je voudrais vraiment savoir une solution qui fonctionne pour une cartographie arbitraire. – ManBugra

+1

Exactement. Le problème est que les signes diacritiques sont parfois combinés, parfois non, et le remplacement caractère par caractère est confus car il y a en réalité deux caractères, pas un. –

+0

@Mr. Brillant et nouveau: oui, System.out.println ("š" .toCharArray(). Length); sorties '2' – ManBugra

0

j'utiliser la méthode replace dans une boucle simple.

String sourceCharacters = "šđćčŠĐĆČžŽ"; 
String targetCharacters = "sdccSDCCzZ"; 

String s = "Gračišće"; 
for (int i=0 ; i<sourceCharacters.length() ; i++) 
    s = s.replace(sourceCharacters.charAt[i], targetCharacters.charAt[i]); 

System.out.println(s); 
+0

chaque itération créerait un nouvel objet chaîne.serait bien de le faire 'en place' – ManBugra

+0

Premièrement, chaque itération ne fait qu'un nouvel objet si une modification est effectuée; Si le caractère recherché n'est pas présent, l'objet d'origine est renvoyé. Deuxièmement, il est de loin plus ennuyeux d'écrire ce code en utilisant StringBuilder ou StringBuffer car vous devez faire tout le travail vous-même; Puisque la gestion de la mémoire de Java est réglée pour le renouvellement rapide des objets de toute façon, il est plus facile de le faire comme je l'ai montré au lieu d'essayer de comprendre comment être efficace. Vous pouvez toujours optimiser plus tard si c'est vraiment nécessaire (c'est-à-dire s'il s'agit d'un véritable goulot d'étranglement). –

+0

oui vous avez raison à votre premier point. mais je ne suis pas d'accord avec votre deuxième. vous écrivez du code efficace une fois, même si c'est ennuyeux, et que vous le réutilisez. En tout cas, BalusC a résolu l'énigme. – ManBugra

Questions connexes