424,054 Members | 1,044 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,054 IT Pros & Developers. It's quick & easy.

How to remove accents (A-Umlaut to A)

P: n/a
Is there a method to replace special characters like (A-Umlaut) with
A, (O-Umlaut) with O, and so on?
Sure, I could look for each character separately and replace it with its
ascii-counterpart, but there are also such special characters in French
and Swedish and many other languages which I also want to catch. Is
there a generic way to do it?
Aug 7 '07 #1
Share this Question
Share on Google+
11 Replies


P: n/a
On Tue, 07 Aug 2007 14:05:46 +0200, cody <de********@gmx.dewrote:
Is there a method to replace special characters like (A-Umlaut) with
A, (O-Umlaut) with O, and so on?
Sure, I could look for each character separately and replace it with its
ascii-counterpart, but there are also such special characters in French
and Swedish and many other languages which I also want to catch. Is
there a generic way to do it?
Hi Cody,

There is no generic way to do this. There is a hack that works in most cases involving switching Encoding the string and reading it in a different encoding, but this is by no means ensured to work for you. Your best bet is to create a lookup table and manually translate each character. If you anticipate a wide variety of characters, maybe Unicode or UTF-8 support is best.

--
Happy coding!
Morten Wennevik [C# MVP]
Aug 7 '07 #2

P: n/a
Morten Wennevik [C# MVP] <Mo************@hotmail.comwrote:
On Tue, 07 Aug 2007 14:05:46 +0200, cody <de********@gmx.dewrote:
Is there a method to replace special characters like (A-Umlaut) with
A, (O-Umlaut) with O, and so on?
Sure, I could look for each character separately and replace it with its
ascii-counterpart, but there are also such special characters in French
and Swedish and many other languages which I also want to catch. Is
there a generic way to do it?
There is no generic way to do this. There is a hack that works in
most cases involving switching Encoding the string and reading it in
a different encoding, but this is by no means ensured to work for
you. Your best bet is to create a lookup table and manually translate
each character. If you anticipate a wide variety of characters, maybe
Unicode or UTF-8 support is best.
Actually, as of .NET 2.0 there *is* a way of doing this using
System.Text.NormalizationForm.

Look at
http://groups.google.com/group/micro...neral/tree/bro
wse_frm/thread/78a09bd184351bc5/99f090af662c126c?rnum=11
(the last response, from Chris Mullins).

Here's the code posted, which does some upper-casing which isn't needed
in this case - but it should be okay aside from that.

Original code:

Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);

string s = ":usdBDlGXHHA";
string normalized = s.Normalize(NormalizationForm.FormKD);
Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);
string newString = ascii.GetString(encodedBytes).ToUpper();
MessageBox.Show(newString);

End of original code.
Here's a slightly simpler (IMO) version:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
Encoding removal = Encoding.GetEncoding
(Encoding.ASCII.CodePage,
new EncoderReplacementFallback(""),
new DecoderReplacementFallback(""));

byte[] bytes = removal.GetBytes(normalized);
return Encoding.ASCII.GetString(bytes);
}

Or an alternative:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
StringBuilder builder = new StringBuilder();
foreach (char c in normalized)
{
if (char.GetUnicodeCategory(c) !=
UnicodeCategory.NonSpacingMark)
{
builder.Append(c);
}
}
return builder.ToString();
}
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Aug 7 '07 #3

P: n/a
On Tue, 07 Aug 2007 19:29:00 +0200, Jon Skeet [C# MVP] <sk***@pobox.comwrote:
Morten Wennevik [C# MVP] <Mo************@hotmail.comwrote:
>On Tue, 07 Aug 2007 14:05:46 +0200, cody <de********@gmx.dewrote:
Is there a method to replace special characters like (A-Umlaut) with
A, (O-Umlaut) with O, and so on?
Sure, I could look for each character separately and replace it with its
ascii-counterpart, but there are also such special characters in French
and Swedish and many other languages which I also want to catch. Is
there a generic way to do it?

There is no generic way to do this. There is a hack that works in
most cases involving switching Encoding the string and reading it in
a different encoding, but this is by no means ensured to work for
you. Your best bet is to create a lookup table and manually translate
each character. If you anticipate a wide variety of characters, maybe
Unicode or UTF-8 support is best.

Actually, as of .NET 2.0 there *is* a way of doing this using
System.Text.NormalizationForm.

Look at
http://groups.google.com/group/micro...neral/tree/bro
wse_frm/thread/78a09bd184351bc5/99f090af662c126c?rnum=11
(the last response, from Chris Mullins).

Here's the code posted, which does some upper-casing which isn't needed
in this case - but it should be okay aside from that.

Original code:

Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);

string s = ":usdBDlGXHHA";
string normalized = s.Normalize(NormalizationForm.FormKD);
Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);
string newString = ascii.GetString(encodedBytes).ToUpper();
MessageBox.Show(newString);

End of original code.
Here's a slightly simpler (IMO) version:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
Encoding removal = Encoding.GetEncoding
(Encoding.ASCII.CodePage,
new EncoderReplacementFallback(""),
new DecoderReplacementFallback(""));
byte[] bytes = removal.GetBytes(normalized);
return Encoding.ASCII.GetString(bytes);
}

Or an alternative:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
StringBuilder builder = new StringBuilder();
foreach (char c in normalized)
{
if (char.GetUnicodeCategory(c) !=
UnicodeCategory.NonSpacingMark)
{
builder.Append(c);
}
}
return builder.ToString();
}

Interesting.

Well, it would remove what is defined as unicode accents, which is what the OP asked, but it does not normalize other characters into ascii, like the Norwegian , in which case only is defined as having an accent, though and could be translated to a and o. The first method would eat and return only a and the second would return a

--
Happy coding!
Morten Wennevik [C# MVP]
Aug 7 '07 #4

P: n/a
Morten Wennevik [C# MVP] <Mo************@hotmail.comwrote:

<snip>
Interesting.

Well, it would remove what is defined as unicode accents, which is
what the OP asked, but it does not normalize other characters into
ascii, like the Norwegian , in which case only is defined as
having an accent, though and could be translated to a and o. The
first method would eat and return only a and the second would
return a
Right. It's a shame there's not better support in the framework for
this, but as it's improved from 1.1 to 2.0 there's a chance it'll get
better in the future :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Aug 7 '07 #5

P: n/a

On Aug 7, 7:59 pm, "Morten Wennevik [C# MVP]"
<MortenWenne...@hotmail.comwrote:
and could be translated to a and o.
I don't think that makes sense for all languages. As far as I
understand Unicode normalization, is normalized as far as Unicode is
concerned, according to the latin normalization chart. Further
decomposition risks emulating the dreaded "silent ASCII treatment"
strings are given by .NET unless you're careful, and should likely
take culture into account. In some regards, I think Unicode
normalization may even defeat the purpose of the ASCII-fication we're
discussing here, since the more information you have about a
character, the better you can ASCII-fy it. In German, is a fancy a,
but not in Swedish, and "normalization" would have to acknowledge
this. But we digress...

Aug 8 '07 #6

P: n/a

On Aug 7, 2:05 pm, cody <deutron...@gmx.dewrote:
Is there a method to replace special characters like [...]
Maybe knowing the reason why you're doing this can help us find you a
better solution?

A common example: turning strings into filenames on non-Unicode file
systems. In this case, using Encoding.ASCII with "" fallback (to avoid
question marks) is in my opinion not problematic, since the whole idea
is to truncate the input strings, and the resemblance between filename
and string is just a bonus. If you don't need that resemblance,
hashing strings makes things easier. If the purpose is something else,
maybe you need a different solution.

Either way, you should be prepared for the contingency that the string
has _only_ characters without ASCII counterparts, for example.

Aug 8 '07 #7

P: n/a
Jon Skeet [C# MVP] wrote:
Morten Wennevik [C# MVP] <Mo************@hotmail.comwrote:
>On Tue, 07 Aug 2007 14:05:46 +0200, cody <de********@gmx.dewrote:
>>Is there a method to replace special characters like (A-Umlaut) with
A, (O-Umlaut) with O, and so on?
Sure, I could look for each character separately and replace it with its
ascii-counterpart, but there are also such special characters in French
and Swedish and many other languages which I also want to catch. Is
there a generic way to do it?
There is no generic way to do this. There is a hack that works in
most cases involving switching Encoding the string and reading it in
a different encoding, but this is by no means ensured to work for
you. Your best bet is to create a lookup table and manually translate
each character. If you anticipate a wide variety of characters, maybe
Unicode or UTF-8 support is best.

Actually, as of .NET 2.0 there *is* a way of doing this using
System.Text.NormalizationForm.

Look at
http://groups.google.com/group/micro...neral/tree/bro
wse_frm/thread/78a09bd184351bc5/99f090af662c126c?rnum=11
(the last response, from Chris Mullins).

Here's the code posted, which does some upper-casing which isn't needed
in this case - but it should be okay aside from that.

Original code:

Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);

string s = ":usdBDlGXHHA";
string normalized = s.Normalize(NormalizationForm.FormKD);
Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);
string newString = ascii.GetString(encodedBytes).ToUpper();
MessageBox.Show(newString);

End of original code.
Here's a slightly simpler (IMO) version:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
Encoding removal = Encoding.GetEncoding
(Encoding.ASCII.CodePage,
new EncoderReplacementFallback(""),
new DecoderReplacementFallback(""));

byte[] bytes = removal.GetBytes(normalized);
return Encoding.ASCII.GetString(bytes);
}

Or an alternative:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
StringBuilder builder = new StringBuilder();
foreach (char c in normalized)
{
if (char.GetUnicodeCategory(c) !=
UnicodeCategory.NonSpacingMark)
{
builder.Append(c);
}
}
return builder.ToString();
}

Thank you very much, this will do it!
Aug 9 '07 #8

P: n/a
Jon Skeet [C# MVP] wrote:
Morten Wennevik [C# MVP] <Mo************@hotmail.comwrote:
>On Tue, 07 Aug 2007 14:05:46 +0200, cody <de********@gmx.dewrote:
>>Is there a method to replace special characters like (A-Umlaut) with
A, (O-Umlaut) with O, and so on?
Sure, I could look for each character separately and replace it with its
ascii-counterpart, but there are also such special characters in French
and Swedish and many other languages which I also want to catch. Is
there a generic way to do it?
There is no generic way to do this. There is a hack that works in
most cases involving switching Encoding the string and reading it in
a different encoding, but this is by no means ensured to work for
you. Your best bet is to create a lookup table and manually translate
each character. If you anticipate a wide variety of characters, maybe
Unicode or UTF-8 support is best.

Actually, as of .NET 2.0 there *is* a way of doing this using
System.Text.NormalizationForm.

Look at
http://groups.google.com/group/micro...neral/tree/bro
wse_frm/thread/78a09bd184351bc5/99f090af662c126c?rnum=11
(the last response, from Chris Mullins).

Here's the code posted, which does some upper-casing which isn't needed
in this case - but it should be okay aside from that.

Original code:

Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);

string s = ":usdBDlGXHHA";
string normalized = s.Normalize(NormalizationForm.FormKD);
Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);
string newString = ascii.GetString(encodedBytes).ToUpper();
MessageBox.Show(newString);

End of original code.
Here's a slightly simpler (IMO) version:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
Encoding removal = Encoding.GetEncoding
(Encoding.ASCII.CodePage,
new EncoderReplacementFallback(""),
new DecoderReplacementFallback(""));

byte[] bytes = removal.GetBytes(normalized);
return Encoding.ASCII.GetString(bytes);
}

Or an alternative:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
StringBuilder builder = new StringBuilder();
foreach (char c in normalized)
{
if (char.GetUnicodeCategory(c) !=
UnicodeCategory.NonSpacingMark)
{
builder.Append(c);
}
}
return builder.ToString();
}

Thank you very much, this will do it!
Aug 9 '07 #9

P: n/a
Jon Skeet [C# MVP] wrote:
Morten Wennevik [C# MVP] <Mo************@hotmail.comwrote:
>On Tue, 07 Aug 2007 14:05:46 +0200, cody <de********@gmx.dewrote:
>>Is there a method to replace special characters like (A-Umlaut) with
A, (O-Umlaut) with O, and so on?
Sure, I could look for each character separately and replace it with its
ascii-counterpart, but there are also such special characters in French
and Swedish and many other languages which I also want to catch. Is
there a generic way to do it?
There is no generic way to do this. There is a hack that works in
most cases involving switching Encoding the string and reading it in
a different encoding, but this is by no means ensured to work for
you. Your best bet is to create a lookup table and manually translate
each character. If you anticipate a wide variety of characters, maybe
Unicode or UTF-8 support is best.

Actually, as of .NET 2.0 there *is* a way of doing this using
System.Text.NormalizationForm.

Look at
http://groups.google.com/group/micro...neral/tree/bro
wse_frm/thread/78a09bd184351bc5/99f090af662c126c?rnum=11
(the last response, from Chris Mullins).

Here's the code posted, which does some upper-casing which isn't needed
in this case - but it should be okay aside from that.

Original code:

Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);

string s = ":usdBDlGXHHA";
string normalized = s.Normalize(NormalizationForm.FormKD);
Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);
string newString = ascii.GetString(encodedBytes).ToUpper();
MessageBox.Show(newString);

End of original code.
Here's a slightly simpler (IMO) version:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
Encoding removal = Encoding.GetEncoding
(Encoding.ASCII.CodePage,
new EncoderReplacementFallback(""),
new DecoderReplacementFallback(""));

byte[] bytes = removal.GetBytes(normalized);
return Encoding.ASCII.GetString(bytes);
}

Or an alternative:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
StringBuilder builder = new StringBuilder();
foreach (char c in normalized)
{
if (char.GetUnicodeCategory(c) !=
UnicodeCategory.NonSpacingMark)
{
builder.Append(c);
}
}
return builder.ToString();
}

Thank you very much, this will do it!
Aug 9 '07 #10

P: n/a
Jon Skeet [C# MVP] wrote:
Morten Wennevik [C# MVP] <Mo************@hotmail.comwrote:
>On Tue, 07 Aug 2007 14:05:46 +0200, cody <de********@gmx.dewrote:
>>Is there a method to replace special characters like (A-Umlaut) with
A, (O-Umlaut) with O, and so on?
Sure, I could look for each character separately and replace it with its
ascii-counterpart, but there are also such special characters in French
and Swedish and many other languages which I also want to catch. Is
there a generic way to do it?
There is no generic way to do this. There is a hack that works in
most cases involving switching Encoding the string and reading it in
a different encoding, but this is by no means ensured to work for
you. Your best bet is to create a lookup table and manually translate
each character. If you anticipate a wide variety of characters, maybe
Unicode or UTF-8 support is best.

Actually, as of .NET 2.0 there *is* a way of doing this using
System.Text.NormalizationForm.

Look at
http://groups.google.com/group/micro...neral/tree/bro
wse_frm/thread/78a09bd184351bc5/99f090af662c126c?rnum=11
(the last response, from Chris Mullins).

Here's the code posted, which does some upper-casing which isn't needed
in this case - but it should be okay aside from that.

Original code:

Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);

string s = ":usdBDlGXHHA";
string normalized = s.Normalize(NormalizationForm.FormKD);
Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);
string newString = ascii.GetString(encodedBytes).ToUpper();
MessageBox.Show(newString);

End of original code.
Here's a slightly simpler (IMO) version:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
Encoding removal = Encoding.GetEncoding
(Encoding.ASCII.CodePage,
new EncoderReplacementFallback(""),
new DecoderReplacementFallback(""));

byte[] bytes = removal.GetBytes(normalized);
return Encoding.ASCII.GetString(bytes);
}

Or an alternative:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
StringBuilder builder = new StringBuilder();
foreach (char c in normalized)
{
if (char.GetUnicodeCategory(c) !=
UnicodeCategory.NonSpacingMark)
{
builder.Append(c);
}
}
return builder.ToString();
}

Thank you very much, this will do it!
Aug 9 '07 #11

P: n/a
Jon Skeet [C# MVP] wrote:
Morten Wennevik [C# MVP] <Mo************@hotmail.comwrote:
>On Tue, 07 Aug 2007 14:05:46 +0200, cody <de********@gmx.dewrote:
>>Is there a method to replace special characters like (A-Umlaut) with
A, (O-Umlaut) with O, and so on?
Sure, I could look for each character separately and replace it with its
ascii-counterpart, but there are also such special characters in French
and Swedish and many other languages which I also want to catch. Is
there a generic way to do it?
There is no generic way to do this. There is a hack that works in
most cases involving switching Encoding the string and reading it in
a different encoding, but this is by no means ensured to work for
you. Your best bet is to create a lookup table and manually translate
each character. If you anticipate a wide variety of characters, maybe
Unicode or UTF-8 support is best.

Actually, as of .NET 2.0 there *is* a way of doing this using
System.Text.NormalizationForm.

Look at
http://groups.google.com/group/micro...neral/tree/bro
wse_frm/thread/78a09bd184351bc5/99f090af662c126c?rnum=11
(the last response, from Chris Mullins).

Here's the code posted, which does some upper-casing which isn't needed
in this case - but it should be okay aside from that.

Original code:

Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);

string s = ":usdBDlGXHHA";
string normalized = s.Normalize(NormalizationForm.FormKD);
Encoding ascii = Encoding.GetEncoding(
"us-ascii",
new EncoderReplacementFallback(string.Empty),
new DecoderReplacementFallback(string.Empty));
byte[] encodedBytes = new byte[ascii.GetByteCount(normalized)];
int numberOfEncodedBytes = ascii.GetBytes(normalized, 0,
normalized.Length,
encodedBytes, 0);
string newString = ascii.GetString(encodedBytes).ToUpper();
MessageBox.Show(newString);

End of original code.
Here's a slightly simpler (IMO) version:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
Encoding removal = Encoding.GetEncoding
(Encoding.ASCII.CodePage,
new EncoderReplacementFallback(""),
new DecoderReplacementFallback(""));

byte[] bytes = removal.GetBytes(normalized);
return Encoding.ASCII.GetString(bytes);
}

Or an alternative:

static string RemoveAccents (string input)
{
string normalized = input.Normalize(NormalizationForm.FormKD);
StringBuilder builder = new StringBuilder();
foreach (char c in normalized)
{
if (char.GetUnicodeCategory(c) !=
UnicodeCategory.NonSpacingMark)
{
builder.Append(c);
}
}
return builder.ToString();
}

Thank you very much, this will do it!
Aug 9 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.