我正试图在Swift中第一次使用正则表达式和范围。我想看看用户输入文本字段的字母是否与他们必须猜测的单词匹配。如果它匹配匹配的字母或字母将显示在UILabel中(类似于你扮演刽子手的方式,如果你猜错了一次正确的字母并且该字母有多次出现,则会显示所有出现的事件)。单击按钮时,将调用以下方法。它在找到匹配的字母并将它们插入正确的位置时工作正常,但在循环后更新UILabel时它只更新带有第二个/最后一个循环结果的标签。如何从循环的所有迭代中获得结果的组合?任何帮助,将不胜感激。谢谢
func findLetter(displayedWord toSearchin: String, userInput toSearchFor: String) {
let ranges: [NSRange]
var labelUpdate = String()
do {
let regex = try NSRegularExpression(pattern: toSearchFor, options: [])
let displayedWord = toSearchin as NSString
let rangeOfSearch = NSMakeRange(0, displayedWord.length)
ranges = regex.matches(in: toSearchin, range: rangeOfSearch).map {$0.range}
let nsStringlabel = wordLabel.text as NSString?
for range in ranges {
labelUpdate = (nsStringlabel?.replacingCharacters(in: range, with: toSearchFor))!
print(labelUpdate)
//the word is lavenders, so this prints:
//___e_____
//______e__
// I want:
//___e__e__
}
DispatchQueue.main.async(execute: {
self.wordLabel.text = labelUpdate
})
}
catch {
ranges = []
}
}
答案 0 :(得分:1)
如评论中所述,您始终更新原始nsStringlabel
变量,因此始终会覆盖先前循环运行中的先前修改。
我建议您使用labelUpdate
初始化wordLabel.text as NSString?
并完全删除nsStringlabel
。这应该可以解决你的问题。
话虽如此,在这个功能中还有很多其他问题可以解决。 特别是,为什么要使用正则表达式?它很贵,在那里没用。 此外,您在设置标签值之前进行调度,这是好的,但在检索值之前没有...要么需要调度,要么不调度,但不能在一个地方而不是另一个地方需要。如果你从主线程调用你的函数(例如作为对用户输入的响应),你应该是好的,不需要派遣。
这就是我要做的事情(应该更安全,更快):
func updateLabel(withDestinationWord destinationWord: String, userInput: String) {
var labelText = wordLabel.text
var startIndex = labelText.characters.startIndex
while let r = destinationWord.range(of: userInput, options: .caseInsensitive, range: startIndex..<labelText.characters.endIndex) {
labelText.replaceSubrange(r, with: userInput)
startIndex = labelText.characters.index(after: r.lowerBound)
}
wordLabel.text = labelText
}
确保wordLabel.text
和destinationWord
的长度相同!