Objective c NSString:从字符串中删除UTF-8重音的简单方法?
我想更改一个句子,例如: Être ou ne pasêtre。塞泰特·拉巴斯 将成为: 你真是太好了。这是我的生日 有什么简单的方法可以使用NSString实现这一点吗?或者我必须通过检查每个字符来自己开发这个吗?你试过了吗Objective c NSString:从字符串中删除UTF-8重音的简单方法?,objective-c,utf-8,nsstring,Objective C,Utf 8,Nsstring,我想更改一个句子,例如: Être ou ne pasêtre。塞泰特·拉巴斯 将成为: 你真是太好了。这是我的生日 有什么简单的方法可以使用NSString实现这一点吗?或者我必须通过检查每个字符来自己开发这个吗?你试过了吗 [string stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]] 或 ? & 。。。或者尝试改用NSUTF8StringEncoding 此处
[string stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]]
或
?
&
。。。或者尝试改用NSUTF8StringEncoding
此处的编码类型列表:
这是一个写下这个伟大答案的单行方法:
yourString = [[NSString alloc]
initWithData:
[yourString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]
encoding:NSASCIIStringEncoding];
马特·汤普森在一次又一次的演讲中谈到了这一点 TL;博士 如果我能做到这一点,那对我来说效果很好 警告
因为很多人在评论中说这应该是公认的答案,所以我想对这种方法提出警告。此方法非常慢,如果需要转换大量字符串/数据,应小心使用此方法只是更新一下,说明可以像在swift中那样完成:
"Être ou ne pas être. C'était là-bas.".stringByFoldingWithOptions(NSStringCompareOptions.DiacriticInsensitiveSearch, locale: NSLocale.currentLocale())
-->“Etre ou ne pas Etre.C'etait la bas.”对于那些想要快速版本的CFStringTransform解决方案的人:
let stripAccentAndDiacritics: (String) -> String = {
var mStringRef = NSMutableString(string: $0) as CFMutableStringRef
CFStringTransform(mStringRef, nil, kCFStringTransformStripCombiningMarks, Boolean(0))
return String(mStringRef)
}
以下是在iPhone 6 iOS 9.0模拟器上使用Swift 2.0在以下解决方案之间进行的性能测试:
- CFStringTransform(任务1)
- stringByFoldingWithOptions(任务2)
Task 1 took 9.49736100435257 seconds.
Task 2 took 1.96649599075317 seconds.
以下是测试:
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:这是完整的代码。
使用函数stringbyfoldignWithOptions
NSString*str1=@“你是我的朋友”;
NSString*str2=[str1 stringByFoldingWithOptions:NSDIACRITICINCINSENSTIVESEARCH
语言环境:[NSLocale systemLocale]];
NSLog(@“%@”,str2)代码>Swift 3(在操场上测试)
用法:
let umlaut = "äöüÄÖÜ"
let stripped = umlaut.stripCombiningMarks //aouAOU
谢谢,但是当我转换UTF-8字符时,例如,a不会变成but?编辑的帖子-抱歉,我使用了错误的编码类型。我的使用ASCII编码的版本在Xcode中工作-也许使用正确的编码对您有效。这似乎假设字符串可以转换为ASCII而不会丢失信息(除了重音)。对于本例可能有效,但在其他字符集中使用语言时远不能保证有效。@vomako您要转换为数据的字符串可能为零-代码在iOS 8下运行良好。@vomako如果您无法解决此问题(使用谷歌和本网站!),那么我建议在此提出一个新问题,并链接到此选项和您的注释以供参考。无需中间NSData转换和UTF-8编码丢失,请参阅解决方案的更改答案。@Regexident我尝试了此操作,但无效,我在CFStringTransform上遇到错误(stringRef,NULL,KCFStringTransformorMTolatin,否);这一行……这是我发现的第二个问题,它具有将NSData转换为可接受答案的“技巧”。您的答案应该是可以接受的,它甚至超过了[input StringByFolding with Options:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]]代码,因为它不需要一个区域。谢谢,在内核基础中有很多很酷的东西应该被批准,并且感谢链接到汤普森的页面。我同意——这是一个更可靠的答案。请注意,字符串必须是<代码> nSututable字符串< /代码>。不是一个NSString*
。回答得很好,很高兴看到更多的快速变化。感谢您回答我关于两种方法性能比较的问题!
let stripAccentAndDiacritics: (String) -> String = {
var mStringRef = NSMutableString(string: $0) as CFMutableStringRef
CFStringTransform(mStringRef, nil, kCFStringTransformStripCombiningMarks, Boolean(0))
return String(mStringRef)
}
Task 1 took 9.49736100435257 seconds.
Task 2 took 1.96649599075317 seconds.
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.")
//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