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"
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.
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
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With