Подтвердить что ты не робот

NSString: простой способ удалить аккорды UTF-8 из строки?

Я хочу изменить предложение, например:

Être ou ne pas être. C'était là-bas.

Стало бы:

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

Есть ли простой способ сделать это с помощью NSString? Или мне нужно разработать это самостоятельно, проверив каждый char?

4b9b3361

Ответ 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)
}