【问题标题】:highlighting difference in text突出文本中的差异
【发布时间】:2019-02-05 01:15:40
【问题描述】:

我想突出显示两个字符串之间的文本差异。第一个字符串是正确的字符串,第二个是用户输入的字符串。它显示了两者之间的拼写和语法错误。下面的例子

我有一个解决方案,先检查每个单词,然后检查每个字母,它在一定程度上确实有效,但并非每种情况都有效。有没有更好的方法?

另一个不能正常工作的例子。

“The”应该是完全红色的,在士兵中只有“i”和“s”应该是红色的。所有的“进入”都应该是红色的。

func colorTextDiff(correctStr:String, answerText:String) -> NSAttributedString {

        var hintTextIndex = 0

        let attribute = NSMutableAttributedString.init(string: correctStr)

        attribute.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.black , range: NSRange.init(location: 0, length: correctStr.count))
        attribute.addAttribute(NSAttributedStringKey.font, value: UIFont.systemFont(ofSize:14.0), range: NSRange.init(location: 0, length: correctStr.count))

        let correctWords = correctStr.split(separator: " ")
        var answerWords = answerText.split(separator: " ")

        var answerWordIndex = 0
        //match on words, when a word doesnt match test the word's character
        for correctWord in correctWords {
            if answerWordIndex>=answerWords.count { break}
            let answerWord = answerWords[answerWordIndex]
            var wrongChar = 0, answerCharIndex = 0
            print("words ", correctWord, " ", answerWord)
            if correctWord.lowercased() != answerWord.lowercased() {
                for c in correctWord {
                    if answerCharIndex>=answerWord.count {
                        let len = correctWord.count-answerCharIndex
                        attribute.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red , range: NSRange.init(location: hintTextIndex, length: len))
                        hintTextIndex += len+1
                        break
                    }
                    let correctChar = String(c)
                    let answerChar = String(answerWord)[answerCharIndex..<answerCharIndex+1]
                    print("chars ", correctChar, " ", answerChar)
                    if correctChar.lowercased() != answerChar.lowercased() {
                        print("hint index: ", hintTextIndex)
                        attribute.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red , range: NSRange.init(location: hintTextIndex+1, length: 1))
                        wrongChar+=1
                    }

                    answerCharIndex+=1

                    hintTextIndex+=1
                }

            } else {
                hintTextIndex += correctWord.count+1
            }
            if(wrongChar<correctWord.count) {answerWordIndex+=1 } //probably a missed word not missed typed word
        }




        hintTextIndex+=1
        return attribute
}

【问题讨论】:

  • 我添加了一个不起作用的案例
  • 是的,我知道这就是我在这里问的原因
  • 我会首先将发现的差异与字符串的颜色区分开来。这些是 2 个独立的任务,将两者的代码放在一个地方会更难理解。

标签: swift string parsing text


【解决方案1】:

这是一个很酷的问题。

这是我的解决方案:

extension NSMutableAttributedString {
  func setCharacterColor(at location: Int) {
    let range = NSRange(location: location, length: 1)
    self.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red, range: range)
  }
}


extension Array where Element == Character {
  func index(of character: Character, greaterThan index: Int) -> Int? {
    for i in index...self.count where self[i] == character {
      return i
    }
    return nil
  }
}


let correctString = "The soldiers stormed into the village just after sunrise"
let incorrectString = "solder stormed village just after sunrise"
let correctArray = Array(correctString)
let incorrectArray = Array(incorrectString)
var correctMutableString = NSMutableAttributedString(string: correctString)

var currentPosition = 0
for char in incorrectArray {
  guard let position = correctArray.index(of: char, greaterThan: currentPosition) else {
    continue
  }
  while currentPosition < position {
    correctMutableString.setCharacterColor(at: currentPosition)
    currentPosition = currentPosition + 1
  }
  currentPosition = position + 1
}

labelCorrect.attributedText = correctMutableString
labelIncorrect.attributedText = NSMutableAttributedString(string: incorrectString)

它仍然是 n 的平方,但这个问题总是相当计算量的。

它通过循环工作,直到找到正确字符串中的字符,并且该字符与不正确字符串中的字符匹配。然后,它会突出显示在该过程中经过的所有字符。关键是它只突出新字符,而不是以前循环过的字符。

【讨论】:

  • 这看起来是一个优雅的解决方案,我稍后会尝试,谢谢。我想知道如何在答案中突出显示文本。例如“solderstormed a village”,将突出显示“a”,因为它不存在于正确的句子中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
  • 2015-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多