Reputation: 2812
Basically, I want to make a program where if you start typing a name, the app will recognize it from the database and fill in the name for you. To do this, if a person types a comma after finishing a name, the app will start recording what the next name is. If it matches as a substring of one of the names in the database, it will fill it in for the user. The issue is that I need to get what part of the name has been filled out so far after the last occurrence of the comma character in the textField string, but I don't know how. For example: User types: "Daniel, Joh" And the app fills in John for you. Thanks.
Upvotes: 5
Views: 5175
Reputation: 1691
Thanks to Rob and Thierry G.
extension String {
var nsRange: NSRange {
return Foundation.NSRange(startIndex ..< endIndex, in: self)
}
subscript(nsRange: NSRange) -> Substring? {
return Range(nsRange, in: self)
.flatMap { self[$0] }
}
func substringAfterLastOccurenceOf(_ char: Character) -> String {
let regex = try! NSRegularExpression(pattern: "\(char)\\s*(\\S[^\(char)]*)$")
if let match = regex.firstMatch(in: self, range: self.nsRange), let result = self[match.range(at: 1)] {
return String(result)
}
return ""
}
}
we can use like this
let subStringAfterLastComma = "Hamilton, A".substringAfterLastOccurenceOf(",")
Upvotes: 1
Reputation: 285280
Simple solution with range(of
and options regularExpression
and backwards
.
It searches for a comma followed by an optional whitespace character.
extension String {
var subStringAfterLastComma : String {
guard let subrange = self.range(of: ",\\s?", options: [.regularExpression, .backwards]) else { return self }
return String(self[subrange.upperBound...])
}
}
let string1 = "Dan".subStringAfterLastComma // "Dan"
let string2 = "Daniel, Joh".subStringAfterLastComma // "Joh"
Upvotes: 1
Reputation: 291
Many thanks to Rob. We can even extend his String extension by including the full answer to the initial question, with any Character:
extension String {
func substringAfterLastOccurenceOf(_ char: Character) -> String {
let regex = try! NSRegularExpression(pattern: "\(char)\\s*(\\S[^\(char)]*)$")
if let match = regex.firstMatch(in: self, range: self.nsRange), let result = self[match.range(at: 1)] {
return String(result)
}
return ""
}
// ... Rob's String extension
}
So we just need to call:
let subStringAfterLastComma = "Hamilton, A".substringAfterLastOccurenceOf(",")
Upvotes: 3
Reputation: 438437
If you really want the characters after the last comma, you could use a regular expression:
let string = "Hamilton, A"
let regex = try! NSRegularExpression(pattern: ",\\s*(\\S[^,]*)$")
if let match = regex.firstMatch(in: string, range: string.nsRange), let result = string[match.range(at: 1)] {
// use `result` here
}
Where, in Swift 4:
extension String {
/// An `NSRange` that represents the full range of the string.
var nsRange: NSRange {
return NSRange(startIndex ..< endIndex, in: self)
}
/// Substring from `NSRange`
///
/// - Parameter nsRange: `NSRange` within the string.
/// - Returns: `Substring` with the given `NSRange`, or `nil` if the range can't be converted.
subscript(nsRange: NSRange) -> Substring? {
return Range(nsRange, in: self)
.flatMap { self[$0] }
}
}
Upvotes: 4