Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert UPPERCASE to Title Case

Tags:

regex

swift

I want to convert an uppercase string (UPPERCASE) into a title case string (Title Case) in swift. I am not strong in regular expressions, but have found this answer with a regular expression that I have attempted to use.

The search expression is:

"([A-Z])([A-Z]+)\b"

and the template expression is:

"$1\L$2"

In order to use it in swift I have escaped the backslashes as seen below:

var uppercase = "UPPER CASE STRING"
var titlecase = uppercase.stringByReplacingOccurrencesOfString("([A-Z])([A-Z]+)\\b", withString: "$1\\L$2", options: NSStringCompareOptions.RegularExpressionSearch, range: Range<String.Index>(start: uppercase.startIndex, end: uppercase.endIndex))

The code above gives the following result:

"ULPPER CLASE SLTRING"

From that you can see that the search expression successfully finds the two parts $1 and $2, but it looks like escaping the backslash interferes with the replacement.

How can I get the expected result of:

"Upper Case String"
like image 214
Marmoy Avatar asked Sep 22 '15 07:09

Marmoy


2 Answers

Many of the useful existing NSString methods are available from Swift. This includes capitalizedString, which may just do exactly what you want, depending on your requirements.

like image 145
Matt Gibson Avatar answered Nov 09 '22 23:11

Matt Gibson


As I know, title cased string is the string that has the first letter of each word capitalised (except for prepositions, articles and conjunctions). So, the code should be like that:

public extension String {
    subscript(range: NSRange) -> Substring {
        get {
            if range.location == NSNotFound {
                return ""
            } else {
                let swiftRange = Range(range, in: self)!
                return self[swiftRange]
            }
        }
    }

    /// Title-cased string is a string that has the first letter of each word capitalised (except for prepositions, articles and conjunctions)
    var localizedTitleCasedString: String {
        var newStr: String = ""

        // create linguistic tagger
        let tagger = NSLinguisticTagger(tagSchemes: [.lexicalClass], options: 0)
        let range = NSRange(location: 0, length: self.utf16.count)
        tagger.string = self

        // enumerate linguistic tags in string
        tagger.enumerateTags(in: range, unit: .word, scheme: .lexicalClass, options: []) { tag, tokenRange, _ in
            let word = self[tokenRange]

            guard let tag = tag else {
                newStr.append(contentsOf: word)
                return
            }

            // conjunctions, prepositions and articles should remain lowercased
            if tag == .conjunction || tag == .preposition || tag == .determiner {
                newStr.append(contentsOf: word.localizedLowercase)
            } else {
                // any other words should be capitalized
                newStr.append(contentsOf: word.localizedCapitalized)
            }
        }
        return newStr
    }
}
like image 41
Vitalii Vashchenko Avatar answered Nov 10 '22 00:11

Vitalii Vashchenko