-
-
Save robertmryan/7fc421b905d22be5063528e64676529a to your computer and use it in GitHub Desktop.
extension StringProtocol where Index == String.Index { | |
func ranges<T: StringProtocol>(of substring: T, options: String.CompareOptions = [], locale: Locale? = nil) -> [Range<Index>] { | |
var ranges: [Range<Index>] = [] | |
while let result = range(of: substring, options: options, range: (ranges.last?.upperBound ?? startIndex)..<endIndex, locale: locale) { | |
ranges.append(result) | |
} | |
return ranges | |
} | |
} |
What if we need to find the exact word in string?
e.g
let myStr = "Administrator or worker in office"
let searchString = "or"
let results = string.ranges(of: searchString) --> Contains 2 ranges
here if we apply the above extension to find ranges of exact word then it will give 2 ranges (one from word Administrator and second itself "or" word), is there any way to find only the exact match of a word?
Background: I need to highlight the word "or" using attributed string, for that i need to find range of word "or".
@kk143g – Personally, I would use the new Regex regular expressions, where /…/
is a regex literal pattern, the pattern to be searched is between the /
delimiters, and where we use \b
to designate a “word boundary”:
let string = "Administrator or worker in office"
let pattern = /\bor\b/
.ignoresCase()
for match in string.matches(of: pattern) {
print(string[match.range])
}
Or, if you needed to support old OS versions, you can use the extension shown above and use the .regularExpression
option:
let string = "Administrator or worker in office"
let ranges = string.ranges(of: #"\bor\b"#, options: [.regularExpression, .caseInsensitive])
for range in ranges {
print(string[range])
}
For the sake of completeness, you could also use the NaturalLanguage framework, but that’s horrible overkill, IMHO.
Or also,
let string = "Administrator or worker in office"
let pattern = Regex {
Anchor.wordBoundary
"or"
Anchor.wordBoundary
}.ignoresCase()
for match in string.matches(of: pattern) {
print(string[match.range])
}
Pursuant to https://stackoverflow.com/a/47220964/1271826, making it generic. This permits, for example, using
Substring
, likerange()
does: