NSString: простой способ удалить аккорды UTF-8 из строки?
Я хочу изменить предложение, например:
Être ou ne pas être. C'était là-bas.
Стало бы:
Etre ou ne pas etre. C'etait la-bas.
Есть ли простой способ сделать это с помощью NSString? Или мне нужно разработать это самостоятельно, проверив каждый char?
Ответы
Ответ 1
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
.
Список типов кодировки здесь:
https://developer.apple.com/documentation/foundation/nsstringencoding
Просто FTR здесь в одну строку способ написать этот отличный ответ:
yourString = [[NSString alloc]
initWithData:
[yourString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]
encoding:NSASCIIStringEncoding];
Ответ 2
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);
Должен сделать трюк, он отлично поработал у меня.
Caveat
Поскольку многие люди в комментариях говорят, что это должен быть принятый ответ, я хочу дать оговорку для этого метода. Этот метод довольно прост, и его следует использовать с осторожностью, если необходимо преобразовать огромное количество строк/данных.
Ответ 3
Вы пробовали
[string stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]]
или
Boolean CFStringTransform (
CFMutableStringRef string,
CFRange *range,
CFStringRef transform,
Boolean reverse
);
?
CFStringTransform и Преобразовать идентификаторы
NSMutableString *string = ...;
CFMutableStringRef stringRef = (__bridge CFMutableStringRef)string;
CFStringTransform(stringRef, NULL, kCFStringTransformToLatin, NO);
NSLog(@"%@", string);
Ответ 4
Просто обновите, чтобы сказать, что это можно сделать так быстро:
"Être ou ne pas être. C'était là-bas.".stringByFoldingWithOptions(NSStringCompareOptions.DiacriticInsensitiveSearch, locale: NSLocale.currentLocale())
- > "Etre ou ne pas etre. C'etait la-bas."
Ответ 5
Здесь Тест производительности с использованием Swift 2.0 на iPhone 6 iOS 9.0 Simulator между решениями, используя:
- CFStringTransform (задача 1)
- stringByFoldingWithOptions (Задача 2)
Задача 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.")
ParkBenchTimer от Klaas: fooobar.com/questions/80794/...
Ответ 6
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
}
}
Использование:
let umlaut = "äöüÄÖÜ"
let stripped = umlaut.stripCombiningMarks //aouAOU
Ответ 7
вот полный код.
используйте функцию stringbyfoldignWithOptions.
NSString *[email protected]"Être ou ne pas être C'était là-bas";
NSString *str2=[str1 stringByFoldingWithOptions:NSDiacriticInsensitiveSearch
locale:[NSLocale systemLocale]];
NSLog(@"%@",str2);
Ответ 8
Для тех, кто хочет получить версию решения CFStringTransform Swift:
let stripAccentAndDiacritics: (String) -> String = {
var mStringRef = NSMutableString(string: $0) as CFMutableStringRef
CFStringTransform(mStringRef, nil, kCFStringTransformStripCombiningMarks, Boolean(0))
return String(mStringRef)
}