Help us understand the problem. What is going on with this article?

Swift 4 でキャメルケースとスネークケースを変換する String 拡張

More than 1 year has passed since last update.

2017-12-16 追記

Swift 4 でも動くように書き直しました。いや〜、様変わりしましたね。

標準ライブラリにない……!!!

ウギャーーー!よく使いそうなのに!
ケースのポリシーが違うシステム間でデータをやりとりするとき(json でデータをやりとりするときとか)、変数名を自動で変換したかったのでしこしこ書いた。

追記: 今は Codable という便利な仕組みがあるので、json でやり取りしたいときのケース変換はそっちを使うほうが良いでしょう。

コード

スネークケース → キャメルケース

// Swift 4 版 (String の extension として実装)
extension String {
    // set `lower = false` in case you want "UpperCamel" output.
    func camelized(lower: Bool = true) -> String {
        guard self != "" else { return self }

        let words = lowercased().split(separator: "_").map({ String($0) })
        let firstWord: String = words.first ?? ""

        let camel: String = lower ? firstWord : String(firstWord.prefix(1).capitalized) + String(firstWord.suffix(from: index(after: startIndex)))
        return words.dropFirst().reduce(into: camel, { camel, word in
            camel.append(String(word.prefix(1).capitalized) + String(word.suffix(from: index(after: startIndex))))
        })
    }
}
// Swift 2 版
// set `lower = false` in case you want "UpperCamel" output.
func snakeIntoCamel (snake:String, lower:Bool=true) -> String {
    let pattern = "(\\w{0,1})_"
    var camel = snake.capitalizedString.stringByReplacingOccurrencesOfString(pattern, withString: "$1",
        options: NSStringCompareOptions.RegularExpressionSearch, range: nil)

    if lower {
        // make the first letter lower case
        let head = snake.substringToIndex(advance(snake.startIndex, 1))
        camel.replaceRange(camel.startIndex...camel.startIndex, with: head.lowercaseString)
    }

    return camel
}

キャメルケース → スネークケース

// Swift 4 版 (String の extension として実装)
extension String {
    var snakenized: String {
        // Ensure the first letter is capital
        let head = String(prefix(1))
        let tail = String(suffix(count - 1))
        let upperCased = head.uppercased() + tail

        let input = upperCased

        // split input string into words with Capital letter
        let pattern = "[A-Z]+[a-z,\\d]*"
        guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
            return ""
        }

        var words:[String] = []

        regex.matches(in: input, options: [], range: NSRange.init(location: 0, length: count)).forEach { match in
            if let range = Range(match.range(at: 0), in: self) {
                words.append(String(self[range]).lowercased())
            }
        }

        return words.joined(separator: "_")
    }
}
// Swift 2 版
func camelIntoSnake (camel:String) -> String {
    // ensure the first letter is capital
    let head = camel.substringToIndex(advance(camel.startIndex, 1))
    var upperCased = camel
    upperCased.replaceRange(camel.startIndex...camel.startIndex, with: head.uppercaseString)

    var input = upperCased as NSString

    // split input string into words
    let pattern = "[A-Z]+[a-z,\\d]*"
    let regex = NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions.allZeros, error: nil)

    var words:[String] = []

    if let matches = regex?.matchesInString(input as String, options: NSMatchingOptions.allZeros, range: NSRange(location: 0, length: input.length)) {
        for match in matches {
            for var i = 0; i < match.numberOfRanges; ++i {
                // make every word in lower case
                words.append(input.substringWithRange(match.rangeAtIndex(i)).lowercaseString)
            }
        }
    }

    return join("_", words)
}

Swift、というか Foundation フレームワークでは正規表現がめっちゃめんどくさいですな。。。
目がぱちぱちするね!

参考

http://www.learnswiftonline.com/reference-guides/string-reference-guide-for-swift/
http://blog.mogmet.com/swift-regular-expression-replace/

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした