NSString:从string中删除UTF-8重音的简单方法?

我想改变一个句子,例如:

Êtreou ne pasêtre。 C'étaitlà-bas。

会成为:

Etre ou ne pas etre。 C'etait la-bas。

有没有简单的方法与NSString做到这一点? 还是我必须通过检查每个字符来自行开发?

NSString *str = @"Être ou ne pas être. C'était là-bas."; NSData *data = [str dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; NSString *newStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; NSLog(@"%@", newStr); 

…或尝试使用NSUTF8StringEncoding来代替。

编码types列表在这里:

https://developer.apple.com/documentation/foundation/nsstringencoding


只是FTR这里是一个一线的方式来写这个伟大的答案:

 yourString = [[NSString alloc] initWithData: [yourString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES] encoding:NSASCIIStringEncoding]; 

Mattt Thompson在NSHipster上报道了这一点,并在WWDC 2013会议上再次报道了这一点

TL; DR

 NSMutableString *str = [@"Être ou ne pas être. C'était là-bas." mutableCopy]; CFStringTransform((__bridge CFMutableStringRef)string, NULL, kCFStringTransformStripCombiningMarks, NO); 

应该做的伎俩,它对我很好。

警告由于很多人在评论中说这应该是我接受的答案,我想给这个方法一个警告。 这个方法非常慢,如果需要转换大量的string/数据,应该小心使用

你有没有尝试过

 [string stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]] 

要么

 Boolean CFStringTransform ( CFMutableStringRef string, CFRange *range, CFStringRef transform, Boolean reverse ); 

CFStringTransform & Transform标识符

 NSMutableString *string = ...; CFMutableStringRef stringRef = (__bridge CFMutableStringRef)string; CFStringTransform(stringRef, NULL, kCFStringTransformToLatin, NO); NSLog(@"%@", string); 

只是一个更新说,它可以这样做迅速:

 "Être ou ne pas être. C'était là-bas.".stringByFoldingWithOptions(NSStringCompareOptions.DiacriticInsensitiveSearch, locale: NSLocale.currentLocale()) 

– >“Etre ou ne pas pasre。C'etait la-bas。”

这里使用Swift 2.0在iPhone 6 iOS 9.0模拟器上进行性能testing,解决scheme使用:

  • CFStringTransform(任务1)
  • stringByFoldingWithOptions(任务2)

任务2一直更快,例如:

 Task 1 took 9.49736100435257 seconds. Task 2 took 1.96649599075317 seconds. 

这里testing:

  let timer = ParkBenchTimer() for _ in 1...1000000 { let mStringRef = NSMutableString(string: "Être ou ne pas être. C'était là-bas.") as CFMutableStringRef CFStringTransform(mStringRef, nil, kCFStringTransformStripCombiningMarks, false) String(mStringRef) } print("Task 1 took \(timer.stop()) seconds.") let timer2 = ParkBenchTimer() for _ in 1...1000000 { "Être ou ne pas être. C'était là-bas.".stringByFoldingWithOptions(NSStringCompareOptions.DiacriticInsensitiveSearch, locale: NSLocale.currentLocale()) } print("Task 2 took \(timer2.stop()) seconds.") 

由Klaas ParkBenchTimer: https ://stackoverflow.com/a/26578191/1097106

这里是完整的代码。 使用函数stringbyfoldignWithOptions。

NSString *str1=@"Être ou ne pas être C'était là-bas"; NSString *str2=[str1 stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale systemLocale]]; NSLog(@"%@",str2);

对于那些想要Swift版本的CFStringTransform解决scheme的人:

 let stripAccentAndDiacritics: (String) -> String = { var mStringRef = NSMutableString(string: $0) as CFMutableStringRef CFStringTransform(mStringRef, nil, kCFStringTransformStripCombiningMarks, Boolean(0)) return String(mStringRef) } 

斯威夫特3 (在操场上testing)

 //String+StripCombiningMarks.swift extension String { /// strip combining marks (accents or diacritics) var stripCombiningMarks: String { let mStringRef = NSMutableString(string: self) as CFMutableString CFStringTransform(mStringRef, nil, kCFStringTransformStripCombiningMarks, false) return mStringRef as String } } 

用法:

 let umlaut = "äöüÄÖÜ" //ÄÖÜ let stripped = umlaut.stripCombiningMarks //aouAOU