Rob*_*Rob 44 objective-c utf-8 nsstring
我想改变一个句子,例如:
pas pas pas pas re re.C'étaitlà-bas.
会成为:
Etre ou ne pas etre.C'etait la-bas.
使用NSString有什么简单的方法吗?或者我必须通过检查每个字符来自己开发它?
Luk*_*uke 58
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);
Run Code Online (Sandbox Code Playgroud)
...或尝试使用NSUTF8StringEncoding.
这里的编码类型列表:
https://developer.apple.com/documentation/foundation/nsstringencoding
只是FTR这里有一个单行方式来写这个伟大的答案:
yourString = [[NSString alloc]
initWithData:
[yourString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]
encoding:NSASCIIStringEncoding];
Run Code Online (Sandbox Code Playgroud)
tap*_*api 48
Mattt Thompson在NSHipster和WWDC 2013会议228上再次讨论了这个问题
TL; DR
NSMutableString *str = [@"Être ou ne pas être. C'était là-bas." mutableCopy];
CFStringTransform((__bridge CFMutableStringRef)string, NULL, kCFStringTransformStripCombiningMarks, NO);
Run Code Online (Sandbox Code Playgroud)
应该做的伎俩,它对我很有用.
警告 由于评论中有很多人说这应该是接受的答案,我想对这种方法提出警告.这种方法非常慢,如果需要转换大量的字符串/数据,应该小心使用
Reg*_*ent 26
你有没有尝试过
[string stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]]
Run Code Online (Sandbox Code Playgroud)
要么
Boolean CFStringTransform (
CFMutableStringRef string,
CFRange *range,
CFStringRef transform,
Boolean reverse
);
Run Code Online (Sandbox Code Playgroud)
?
NSMutableString *string = ...;
CFMutableStringRef stringRef = (__bridge CFMutableStringRef)string;
CFStringTransform(stringRef, NULL, kCFStringTransformToLatin, NO);
NSLog(@"%@", string);
Run Code Online (Sandbox Code Playgroud)
val*_*alR 16
只是更新说它可以像在swift中那样完成:
"Être ou ne pas être. C'était là-bas.".stringByFoldingWithOptions(NSStringCompareOptions.DiacriticInsensitiveSearch, locale: NSLocale.currentLocale())
Run Code Online (Sandbox Code Playgroud)
- >"Etre ou ne pas etre.C'etait la-bas."
这里使用Swift 2.0在iPhone 6 iOS 9.0模拟器上使用以下解决方案进行性能测试:
任务2始终更快,例如:
Task 1 took 9.49736100435257 seconds.
Task 2 took 1.96649599075317 seconds.
Run Code Online (Sandbox Code Playgroud)
在这里测试:
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.")
Run Code Online (Sandbox Code Playgroud)
Klaas的ParkBenchTimer:https://stackoverflow.com/a/26578191/1097106
Swift 3 (在操场上测试)
//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
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
let umlaut = "äöüÄÖÜ"
let stripped = umlaut.stripCombiningMarks //aouAOU
Run Code Online (Sandbox Code Playgroud)