我的Swift应用程序涉及在UITextView中搜索文本。用户可以在该文本视图中搜索某个子字符串,然后在文本视图中跳转到该字符串的任何实例(例如,第三个实例)。我需要找出它们所在的字符的整数值。
例如:
示例1:用户搜索" hello"并且文本视图显示"嘿嗨你好,嘿嗨你好"然后用户按下箭头查看第二个实例。我需要知道第二个hello中第一个h
的整数值(即hello中的哪个#字符在文本视图中)。整数值应为22
。
示例2:用户搜索" abc"而文本视图显示" abcd"并且他们正在寻找abc
的第一个实例,因此整数值应该是1
(这是a
的整数值,因为它是该name='documentation'
的第一个字符。他们正在寻找的实例。
如何获取用户正在搜索的字符的索引?
答案 0 :(得分:10)
试试这样:
let sentence = "hey hi hello, hey hi hello"
let query = "hello"
var searchRange = sentence.startIndex..<sentence.endIndex
var indexes: [String.Index] = []
while let range = sentence.rangeOfString(query, options: .CaseInsensitiveSearch, range: searchRange) {
searchRange = range.endIndex..<searchRange.endIndex
indexes.append(range.startIndex)
}
print(indexes) // "[7, 21]\n"
Xcode 8 beta 6•Swift 3
while let range = sentence.range(of: query, options: .caseInsensitive, range: searchRange) {
searchRange = range.upperBound..<searchRange.upperBound
indexes.append(range.lowerBound)
}
答案 1 :(得分:3)
另一种方法是NSRegularExpression
,旨在轻松迭代字符串中的匹配项。如果你使用.ignoreMetacharacters
选项,它将不会应用任何复杂的通配符/正则表达式逻辑,但只会查找有问题的字符串。所以考虑一下:
let string = "hey hi hello, hey hi hello" // string to search within
let searchString = "hello" // string to search for
let matchToFind = 2 // grab the second occurrence
let regex = try! NSRegularExpression(pattern: searchString, options: [.caseInsensitive, .ignoreMetacharacters])
您可以使用enumerateMatches
:
var count = 0
let range = NSRange(string.startIndex ..< string.endIndex, in: string)
regex.enumerateMatches(in: string, range: range) { result, _, stop in
count += 1
if count == matchToFind {
print(result!.range.location)
stop.pointee = true
}
}
或者你可以用matches(in:range:)
找到所有这些,然后抓住第一个:
let matches = regex.matches(in: string, range: range)
if matches.count >= matchToFind {
print(matches[matchToFind - 1].range.location)
}
显然,如果您如此倾向,可以省略.ignoreMetacharacters
选项并允许用户执行正则表达式搜索(例如通配符,全字搜索,单词开头等)。
对于Swift 2,请参阅previous revision of this answer。