87

I want to change this sentence :

Et ça sera sa moitié.

To :

Et ca sera sa moitie.

Is there an easy way to do this in Java, like I would do in Objective-C ?

NSString *str = @"Et ça sera sa moitié.";
NSData *data = [str dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *newStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
Tom Blodget
  • 19,489
  • 2
  • 37
  • 64
Rob
  • 15,407
  • 20
  • 67
  • 106

5 Answers5

171

Finally, I've solved it by using the Normalizer class.

import java.text.Normalizer;

public static String stripAccents(String s) 
{
    s = Normalizer.normalize(s, Normalizer.Form.NFD);
    s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
    return s;
}
Abdull
  • 24,646
  • 24
  • 120
  • 168
Rob
  • 15,407
  • 20
  • 67
  • 106
  • Is this removing characters, or replaces characters with accents to equivalents without accents? Im asking, because this: `replaceAll("[^\\p{ASCII}]", "")` looks like replacement with nothing (removing). – Kamil Mar 03 '13 at 21:26
  • You're right, I just edited my answer (the aim is of course to replace and not remove the characters). – Rob Mar 03 '13 at 21:28
  • 2
    In order to correctly transform some strings, I used **`Form.NFKD`** ("Compatibility decomposition.") – Anthony O. Jul 24 '13 at 12:31
  • I used this to normalize the filename. – Diego Macario Apr 08 '16 at 12:56
  • It seems that Normalizer is deprecated and Normalizer2 should be use instead http://icu-project.org/apiref/icu4j/com/ibm/icu/text/Normalizer2.html – ykatchou Feb 12 '19 at 12:14
  • @ykatchou, what makes you believe `java.text.Normalizer` to be deprecated? – Abdull Mar 13 '19 at 17:49
  • See here : http://icu-project.org/apiref/icu4j/com/ibm/icu/text/Normalizer.html ("This API has been replaced by the Normalizer2 class and is only available for backward compatibility") – ykatchou Sep 03 '19 at 13:33
  • 1
    @ykatchou you refer to "com.ibm.icu.text.Normalizer", but answer is about "java.text.Normalizer" – David S. Sep 30 '19 at 12:20
  • But it changes the sense of text on different languages: stripAccents("йод,ëлка,wäre") //иод,елка,ware. How to remove only acute accents? Or any selected set of diacritics? – KursikS Oct 08 '20 at 11:15
112

Maybe the easiest and safest way is using StringUtils from Apache Commons Lang

StringUtils.stripAccents(String input)

Removes diacritics (~= accents) from a string. The case will not be altered. For instance, 'à' will be replaced by 'a'. Note that ligatures will be left as is.

StringUtils.stripAccents()

Ondrej Bozek
  • 10,336
  • 6
  • 52
  • 68
11

I guess the only difference is that I use a + and not a [] compared to the solution. I think both works, but it's better to have it here as well.

String normalized = Normalizer.normalize(input, Normalizer.Form.NFD);
String accentRemoved = normalized.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
EpicPandaForce
  • 75,743
  • 26
  • 240
  • 404
7

For kotlin

fun stripAccents(s: String): String 
{
    var string = Normalizer.normalize(s, Normalizer.Form.NFD)
    string = Regex("\\p{InCombiningDiacriticalMarks}+").replace(string, "")
    return  string
}
Tristan Richard
  • 2,607
  • 1
  • 14
  • 17
5

Assuming you are using Java 6 or newer, you might want to take a look at Normalizer, which can decompose accents, then use a regex to strip the combining accents.

Otherwise, you should be able to achieve the same result using ICU4J.

hertzsprung
  • 8,558
  • 4
  • 36
  • 72