id:alzaが少し前に半角カナを全角カナに変換する。 - アルザえもんの手記のような記事を書いているのを思い出しました。
それぞれのコードで同じ処理を書くのは面倒ですし、変数transformと変数reverseの組み合わせで「カタカナからひらがな」なのか「ひらがなからカタカナ」なのか、少し判断に迷いバグを混入してしまいそうです。他のプロジェクトでも使えるようにNSString型を拡張してカテゴリで実装してみました。あとはこのソースコードを取り込めばNSDateの拡張機能が使えるという寸法です。
CFMutableString Referenceを読む限りでは、CFStringTransform関数以外にも便利そうな関数がありましたので、こちらの方も追々フォローできれば良いかなと考えています。
id:alzaが変換に使用していたCFStringTransform関数は以下のようになっています。
Perform in-place transliteration on a mutable string.
Boolean CFStringTransform (
CFMutableStringRef string,
CFRange *range,
CFStringRef transform,
Boolean reverse
);
第3引数のtransformには、以下の既定の定義を指定し、第4引数にてどちらからどちらへの変換かを指定します。
const CFStringRef kCFStringTransformStripCombiningMarks; const CFStringRef kCFStringTransformToLatin; const CFStringRef kCFStringTransformFullwidthHalfwidth; const CFStringRef kCFStringTransformLatinKatakana; const CFStringRef kCFStringTransformLatinHiragana; const CFStringRef kCFStringTransformHiraganaKatakana; const CFStringRef kCFStringTransformMandarinLatin; const CFStringRef kCFStringTransformLatinHangul; const CFStringRef kCFStringTransformLatinArabic; const CFStringRef kCFStringTransformLatinHebrew; const CFStringRef kCFStringTransformLatinThai; const CFStringRef kCFStringTransformLatinCyrillic; const CFStringRef kCFStringTransformLatinGreek; const CFStringRef kCFStringTransformToXMLHex; const CFStringRef kCFStringTransformToUnicodeName; const CFStringRef kCFStringTransformStripDiacritics;
日本語で関係ありそうなのは以下の4つでしょうか。
kCFStringTransformFullwidthHalfwidth | 全角⇔半角 |
kCFStringTransformHiraganaKatakana | ひらがな⇔カタカナ |
kCFStringTransformLatinHiragana | ローマ字⇔ひらがな |
kCFStringTransformLatinKatakana | ローマ字⇔カタカナ |
NSString+Henkan.h
// // NSString+Henkan.h // // // Created by Kenji Wada ( http://ch3cooh.jp/ ) on 12/06/19. // Copyright (c) 2012 Softbuild. All rights reserved. // #import <Foundation/Foundation.h> @interface NSString (NSString_Henkan) // 半角→全角 - (NSString*) stringToFullwidth; // 全角→半角 - (NSString*) stringToHalfwidth; // カタカナ→ひらがな - (NSString*) stringKatakanaToHiragana; // ひらがな→カタカナ - (NSString*) stringHiraganaToKatakana; // ひらがな→ローマ字 - (NSString*) stringHiraganaToLatin; // ローマ字→ひらがな - (NSString*) stringLatinToHiragana; // カタカナ→ローマ字 - (NSString*) stringKatakanaToLatin; // ローマ字→カタカナ - (NSString*) stringLatinToKatakana; @end
NSString+Henkan.m
// // NSString+Henkan.m // // Created by Kenji Wada ( http://ch3cooh.jp/ ) on 12/06/19. // Copyright (c) 2012 Softbuild. All rights reserved. // #import "NSString+Henkan.h" @implementation NSString (Henkan) - (NSString*) stringTransformWithTransform:(CFStringRef)transform reverse:(Boolean)reverse { NSMutableString* retStr = [[NSMutableString alloc] initWithString:self]; CFStringTransform((CFMutableStringRef)retStr, NULL, transform, reverse); return [retStr autorelease]; } - (NSString*) stringToFullwidth { return [self stringTransformWithTransform:kCFStringTransformFullwidthHalfwidth reverse:true]; } - (NSString*) stringToHalfwidth { return [self stringTransformWithTransform:kCFStringTransformFullwidthHalfwidth reverse:false]; } - (NSString*) stringKatakanaToHiragana { return [self stringTransformWithTransform:kCFStringTransformHiraganaKatakana reverse:true]; } - (NSString*) stringHiraganaToKatakana { return [self stringTransformWithTransform:kCFStringTransformHiraganaKatakana reverse:false]; } - (NSString*) stringHiraganaToLatin { return [self stringTransformWithTransform:kCFStringTransformLatinHiragana reverse:true]; } - (NSString*) stringLatinToHiragana { return [self stringTransformWithTransform:kCFStringTransformLatinHiragana reverse:false]; } - (NSString*) stringKatakanaToLatin { return [self stringTransformWithTransform:kCFStringTransformLatinKatakana reverse:true]; } - (NSString*) stringLatinToKatakana { return [self stringTransformWithTransform:kCFStringTransformLatinKatakana reverse:false]; } @end
テストコード
// // unittest_string.m // // Created by Kenji Wada ( http://ch3cooh.jp/ ) on 12/06/19. // Copyright (c) 2012 Softbuild. All rights reserved. // #import <Foundation/Foundation.h> #import <SenTestingKit/SenTestingKit.h> #import "NSString+Henkan.h" @interface unittest_string : SenTestCase @end #pragma mark - @implementation unittest_string - (void)testFullToHalf { NSString* temp = @"アイウエオ"; NSString* result = [temp stringToHalfwidth]; STAssertTrue([result isEqualToString:@"アイウエオ"] , @"result:%@ is not アイウエオ.", result); } - (void)testHalfToFull { NSString* temp = @"アイウエオ"; NSString* result = [temp stringToFullwidth]; STAssertTrue([result isEqualToString:@"アイウエオ"] , @"result:%@ is not アイウエオ.", result); } - (void)testKanaToHira { NSString* temp = @"アイウエオ"; NSString* result = [temp stringKatakanaToHiragana]; STAssertTrue([result isEqualToString:@"あいうえお"] , @"result:%@ is not あいうえお.", result); } - (void)testHiraToKana { NSString* temp = @"あいうえお"; NSString* result = [temp stringHiraganaToKatakana]; STAssertTrue([result isEqualToString:@"アイウエオ"] , @"result:%@ is not アイウエオ.", result); } - (void)testRomajiToHira { NSString* temp = @"aiueo"; NSString* result = [temp stringLatinToHiragana]; STAssertTrue([result isEqualToString:@"あいうえお"] , @"result:%@ is not あいうえお.", result); } - (void)testHiraToRomaji { NSString* temp = @"あいうえお"; NSString* result = [temp stringHiraganaToLatin]; STAssertTrue([result isEqualToString:@"aiueo"] , @"result:%@ is not aiueo.", result); } - (void)testRomajiToKana { NSString* temp = @"aiueo"; NSString* result = [temp stringLatinToKatakana]; STAssertTrue([result isEqualToString:@"アイウエオ"] , @"result:%@ is not アイウエオ.", result); } - (void)testKanaToRomaji { NSString* temp = @"アイウエオ"; NSString* result = [temp stringKatakanaToLatin]; STAssertTrue([result isEqualToString:@"aiueo"] , @"result:%@ is not aiueo.", result); } @end