22

Does anyone knows hoe to get a NSString like "ÁlgeBra" to "Algebra", without the accent, and capitalize only the first letter?

Thanks,

RL

Rui Lopes
  • 2,562
  • 6
  • 34
  • 49

3 Answers3

56

dreamlax has already mentioned the capitalizedString method. Instead of doing a lossy conversion to and from NSData to remove the accented characters, however, I think it is more elegant to use the stringByFoldingWithOptions:locale: method.

NSString *accentedString = @"ÁlgeBra";
NSString *unaccentedString = [accentedString stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]];
NSString *capitalizedString = [unaccentedString capitalizedString];

Depending on the nature of the strings you want to convert, you might want to set a fixed locale (e.g. English) instead of using the user's current locale. That way, you can be sure to get the same results on every machine.

Community
  • 1
  • 1
Ole Begemann
  • 135,006
  • 31
  • 278
  • 256
  • 3
    *This* is the correct answer. Don't do the silly NSData <-> NSString business that dreamlax suggests. – thefaj Jul 30 '12 at 22:48
  • 1
    The allowLossyConversion technique did handle some scenarios that I couldn't do with NSLocale. For exmaple if I have the following string: ßÄÆûñ. When I run the stringByFoldingWithOptions I get: ßAÆun. When I run the allowLossyConversion I get: sAAEun. In my case I want the second option. Is there a way to get a similar answer using less of a hack? – Alex Sep 28 '12 at 18:59
  • 4
    @Alex: It's not a hack, Apple recommend the `allowLossyConversion` approach in their documentation to transform an ellipsis character to three ASCII periods. @thefaj inappropriately named this technique wrong but it is in fact a legitimate approach. – dreamlax Oct 10 '12 at 03:27
  • What would happen if you passed in Japanese, Arabic, Chinese, etc. characters into the allowLossyConversion technique? You certainly don't want to convert them to ASCII strings. – Tap Forms Oct 20 '12 at 21:09
  • @TapForms: That depends on the desired result. – dreamlax Oct 22 '12 at 10:39
  • @dreamlax -- You are wrong, and your method is incorrect, hackey, and poor style. Use Ole's method as described above. --- To the other developers reading this, vote this answer up and dreamlax's down. – thefaj Nov 13 '12 at 00:57
  • @thefaj: Then why is it on [**Apple's own documentation**](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/CreatingStrings.html) as a method of collapsing certain Unicode characters to ASCII? – dreamlax Nov 13 '12 at 03:20
  • Sometimes you _do_ want lossy conversion, like filenames that don't accept Japanese, Chinese, emoji, etc. So it really depends on the desired result as @dreamlax said – leonaka May 27 '17 at 00:52
13

NSString has a method called capitalizedString:

Return Value

A string with the first character from each word in the receiver changed to its corresponding uppercase value, and all remaining characters set to their corresponding lowercase values.

NSString *str = @"AlgeBra";
NSString *other = [str capitalizedString];

NSLog (@"Old: %@, New: %@", str, other);

Edit:

Just saw that you would like to remove accents as well. You can go through a series of steps:

// original string
NSString *str = @"ÁlgeBra";

// convert to a data object, using a lossy conversion to ASCII
NSData *asciiEncoded = [str dataUsingEncoding:NSASCIIStringEncoding
                         allowLossyConversion:YES];

// take the data object and recreate a string using the lossy conversion
NSString *other = [[NSString alloc] initWithData:asciiEncoded
                                        encoding:NSASCIIStringEncoding];
// relinquish ownership
[other autorelease];

// create final capitalized string
NSString *final = [other capitalizedString];

The documentation for dataUsingEncoding:allowLossyConversion: explicitly says that the letter ‘Á’ will convert to ‘A’ when converting to ASCII.

dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • 3
    Don't do this. It is wrong -- See Ole Begemann's response below. – thefaj Jul 30 '12 at 22:48
  • When I try this I get a "?" character instead of the "OE" as expected. I'm testing this on iOS 6. Has anyone had any luck with this technique? – Tap Forms Oct 22 '12 at 08:52
  • @TapForms: File a bug at Apple. It works with Æ so there's no reason it shouldn't work with Œ. – dreamlax Oct 22 '12 at 10:38
  • @dreamlax Yes, it must be a bug. I just tested your code with this string: @"Œ Æ ß" and this is the result I got: "? AE s". The OE is coming out wrong. I may just have to add a special case for OE and file a bug. – Tap Forms Oct 22 '12 at 16:57
  • This method worked perfectly for me to convert city names for searching. Gdańsk to Gdansk, Córdoba to Cordoba – Tom Kincaid May 03 '14 at 12:22
1

Here's a step by step example of how to do it. There's room for improvement, but you get the basic idea......

NSString *input = @"ÁlgeBra";
NSString *correctCase = [NSString stringWithFormat:@"%@%@",
                           [[input substringToIndex:1] uppercaseString],
                           [[input substringFromIndex:1] lowercaseString]];

NSString *result = [[[NSString alloc] initWithData:[correctCase dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES] encoding:NSASCIIStringEncoding] autorelease];

NSLog( @"%@", result );
Darren Oster
  • 9,146
  • 10
  • 48
  • 66
zrzka
  • 20,249
  • 5
  • 47
  • 73