8
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Swift] 文字の種類ごとに全角/半角に変換する

Posted at

とある案件で,入力された文字のうち,数字は半角,カタカナは全角に変換してほしい,というものがありました.

どうせなら,ということで,数字,英字,カタカナ,その他(記号)ごとに全角/半角を指定できるようなString型のExtensionを作りましたので,共有したいと思います.

ぱっと作ったので,もっといい方法があるかもしれません.
もっと簡単にできる方法がありましたら,コメントの方でご教授お願いしますm(._.)m

関連部分コード

細かい説明は省きます.

enum CharacterType {
    case Numeric, English, Katakana, Other
}

func transformFullwidthHalfwidth(transformTypes types :[CharacterType], reverse :Bool=false) -> String {
    var transformedChars :[String] = []
   
    let chars = self.characters.map{ String($0) }
    chars.forEach{
        let halfwidthChar = NSMutableString(string: $0) as CFMutableString
        CFStringTransform(halfwidthChar, nil, kCFStringTransformFullwidthHalfwidth, false)
        let char = halfwidthChar as String
        
        if char.isNumber(transformHalfwidth: true) {
            if let _ = types.filter({$0 == .Numeric}).first {
                CFStringTransform(halfwidthChar, nil, kCFStringTransformFullwidthHalfwidth, reverse)
                transformedChars.append(halfwidthChar as String)
            } else {
                transformedChars.append($0)
            }
        }
        else if char.isEnglish(transformHalfwidth: true) {
            if let _ = types.filter({$0 == .English}).first {
                CFStringTransform(halfwidthChar, nil, kCFStringTransformFullwidthHalfwidth, reverse)
                transformedChars.append(halfwidthChar as String)
            } else {
                transformedChars.append($0)
            }
        }
        else if char.isKatakana() {
            if let _ = types.filter({$0 == .Katakana}).first {
                CFStringTransform(halfwidthChar, nil, kCFStringTransformFullwidthHalfwidth, reverse)
                transformedChars.append(halfwidthChar as String)
            } else {
                transformedChars.append($0)
            }
        }
        else {
            if let _ = types.filter({$0 == .Other}).first {
                CFStringTransform(halfwidthChar, nil, kCFStringTransformFullwidthHalfwidth, reverse)
                transformedChars.append(halfwidthChar as String)
            } else {
                transformedChars.append($0)
            }
        }
    }
    
    var transformedString = ""
    transformedChars.forEach{ transformedString += $0 }
    
    return transformedString
}

func isNumber(transformHalfwidth transform :Bool) -> Bool {
    let halfwidthStr = NSMutableString(string: self) as CFMutableString
    CFStringTransform(halfwidthStr, nil, kCFStringTransformFullwidthHalfwidth, false)
    let str = halfwidthStr as String
 
    return Int(str) != nil ? true : false
}

func isEnglish(transformHalfwidth transform :Bool) -> Bool {
    let halfwidthStr = NSMutableString(string: self) as CFMutableString
    if transform {
        CFStringTransform(halfwidthStr, nil, kCFStringTransformFullwidthHalfwidth, false)
    }
    let str = halfwidthStr as String
    
    let pattern = "[A-z]*"
    do {
        let regex = try NSRegularExpression(pattern: pattern, options: .CaseInsensitive)
        let result = regex.stringByReplacingMatchesInString(str, options: [], range: NSMakeRange(0, str.characters.count), withTemplate: "")
        if result == "" { return true }
        else { return false }
    }
    catch { return false }
}

func isKatakana() -> Bool {
    let halfwidthStr = NSMutableString(string: self) as CFMutableString
    CFStringTransform(halfwidthStr, nil, kCFStringTransformFullwidthHalfwidth, true)
    let str = halfwidthStr as String
    
    let pattern = "^[\\u30A0-\\u30FF]+$"
    do {           
        let regex = try NSRegularExpression(pattern: pattern, options: .CaseInsensitive)
        let result = regex.stringByReplacingMatchesInString(str, options: [], range: NSMakeRange(0, str.characters.count), withTemplate: "")
        if result == "" { return true }
        else { return false }
    }
    catch { return false }
}

実行結果

let str = "aAこンニチハ123456-+ー=+"
print("そのまま            :", str)
print("カタカナ            :", str.transformFullwidthHalfwidth(transformTypes: [.Katakana]))
print("数字               :", str.transformFullwidthHalfwidth(transformTypes: [.Numeric]))
print("英字               :", str.transformFullwidthHalfwidth(transformTypes: [.English]))
print("その他             :", str.transformFullwidthHalfwidth(transformTypes: [.Other]))
print("英数字             :", str.transformFullwidthHalfwidth(transformTypes: [.Numeric, .English]))
print("カタカナ(全角)       :", str.transformFullwidthHalfwidth(transformTypes: [.Katakana], reverse: true))
print(
    "数字半角,カタカナ全角 :",
    str.transformFullwidthHalfwidth(transformTypes: [.Numeric])
        .transformFullwidthHalfwidth(transformTypes: [.Katakana], reverse: true)
)

// 出力 ----------
//そのまま            : aAこンニチハ123456-+ー=+
//カタカナ            : aAこンニチハ123456-+ー=+
//数字               : aAこンニチハ123456-+ー=+
//英字               : aAこンニチハ123456-+ー=+
//その他             : aAこンニチハ123456-+ー=+
//英数字             : aAこンニチハ123456-+ー=+
//カタカナ(全角)       : aAこンニチハ123456-+ー=+
//数字半角,カタカナ全角 : aAこンニチハ123456-+ー=+
8
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?