46

たとえば、文を変更したい:

生きるべきか、死ぬべきか。C'étaitlà-bas。

になります:

生きるべきか。C'etaitla-bas。

NSStringでこれを行う簡単な方法はありますか?それとも、各文字をチェックして自分でこれを開発する必要がありますか?

4

8 に答える 8

59
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だけで、このすばらしい答えを1行で書くことができます。

yourString = [[NSString alloc]
  initWithData:
    [yourString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]
  encoding:NSASCIIStringEncoding];
于 2012-06-07T13:12:36.087 に答える
48

Mattt Thompsonは、これをNSHipsterで取り上げ、WWDC2013セッション228でも取り上げました。

TL; DR

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

トリックを行う必要があります、それは私にとってはうまくいきました。

警告 コメントの多くの人がこれが受け入れられた答えであるべきだと言っているので、私はこの方法に警告を与えたいと思います。この方法はかなり遅いので、大量の文字列/データを変換する必要がある場合は注意して使用する必要があります

于 2013-08-19T18:43:28.920 に答える
27

やってみました

[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);
于 2012-06-07T13:09:27.670 に答える
16

それは迅速にそのように行うことができると言うための単なる更新:

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

->「生きるべきか、死ぬべきか、死ぬべきか」

于 2015-01-25T22:02:32.533 に答える
9

ここでは、iPhone 6 iOS 9.0SimulatorでSwift2.0を使用したパフォーマンステストを、以下を使用したソリューション間でテストします。

  • 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.")

KlaasによるParkBenchTimer:https ://stackoverflow.com/a/26578191/1097106

于 2015-09-25T13:00:50.840 に答える
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
于 2017-04-13T11:23:45.467 に答える
3

ここに完全なコードがあります。関数stringbyfoldignWithOptionsを使用します。

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

于 2016-06-23T07:02:27.570 に答える
1

CFStringTransformソリューションのSwiftバージョンが必要な場合:

let stripAccentAndDiacritics: (String) -> String = {
    var mStringRef = NSMutableString(string: $0) as CFMutableStringRef
    CFStringTransform(mStringRef, nil, kCFStringTransformStripCombiningMarks, Boolean(0))
    return String(mStringRef)
}
于 2015-05-06T09:11:37.333 に答える