在 Swift 中更改属性字符串的文本并保留属性

Dan*_*n M 5 string string-substitution nsmutablestring swift

对于数据库程序中的输出,我插入了某些文本以指示粗体或斜体,以及一些替换图像的文本。例如:

“%Important%^所有员工到休息室^”的最终输出应为:

重要事项 所有员工到休息室

我编写了代码来查找周围带有“%”符号和“^”符号的文本,但我现在遇到的问题是文本输出,例如:

%重要% ^所有员工到休息室^

我想删除这些 % 和 ^,同时保留字符串的格式。

这是我一直使用的代码,直到它崩溃:

func processText(inString string: String) -> NSAttributedString {

let pattern = ["(?<=\\^).*?(?=\\^)","(?<=\\%).*?(?=\\%)","\\^", "\\%"]
let italicsRegex = NSRegularExpression(pattern: pattern[0], options: .allZeros, error: nil)
let range = NSMakeRange(0, count(string))
let italicsMatches = italicsRegex?.matchesInString(string, options: .allZeros, range: range) as? [NSTextCheckingResult]

var attributedText = NSMutableAttributedString(string: string)

for match in italicsMatches! {
    attributedText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Oblique", size: 14.0)!, range: match.range)
}

let boldRegex = NSRegularExpression(pattern: pattern[1], options: .allZeros, error: nil)
let boldMatches = boldRegex?.matchesInString(string, options: .allZeros, range: range) as? [NSTextCheckingResult]

for match in boldMatches!   {
    attributedText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Bold", size: 14.0)!, range: match.range)
}

let removeItalicsMarksRegex = NSRegularExpression(pattern: pattern[2], options: .allZeros, error: nil)
let removeItalicsMarksMatches = removeItalicsMarksRegex?.matchesInString(string, options: .allZeros, range: range) as? [NSTextCheckingResult]

var numberOfLoops = 0
for match in removeItalicsMarksMatches! {

    attributedText.replaceCharactersInRange(match.range, withString: "")

}

return attributedText.copy() as! NSAttributedString
}
Run Code Online (Sandbox Code Playgroud)

这适用于 % 匹配(但仅适用于第一个字符),并会立即导致 ^ 字符崩溃。

任何解决此问题的帮助或建议将不胜感激。谢谢。

Dan*_*n M 2

马丁,

我最终使用了非常相似的东西,但我决定更改正则表达式以包含 ^ 标记。这样做时,我能够使用“replaceCharactersInRange”方法剪辑所包含的属性子字符串的第一个和最后一个字符。到目前为止,这对我的目的来说效果更好一些,因为它是根据属性字符串工作的,所以它不会搞砸或删除它的任何属性。

我附上了正则表达式和处理斜体的代码部分,供任何人将来参考(再次感谢!):

func processText(inString string: String) -> NSAttributedString {

let pattern = ["\\^.*?\\^"] //Presented as an array here because in the full code there are a lot of patterns that are run.




let italicsRegex = NSRegularExpression(pattern: pattern[0], options: .allZeros, error: nil) 

//In addition to building the match for this first regular expression, I also gather build the regular expressions and gather matches for all other matching patterns on the initial string ("string") before I start doing any processing.

    let range = NSMakeRange(0, count(string.utf16))

let italicsMatches = italicsRegex?.matchesInString(string, options: .allZeros, range: range) as? [NSTextCheckingResult]

var attributedText = NSMutableAttributedString(string: string)

var charactersRemovedFromString = 0

for match in italicsMatches! {

    let newRange = NSMakeRange(match.range.location - charactersRemovedFromString, match.range.length) // Take the updated range for when this loop iterates, otherwise this crashes.
    attributedText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Oblique", size: 12.0)!, range: newRange)

    let rangeOfFirstCharacter = NSMakeRange(match.range.location - charactersRemovedFromString, 1)

    attributedText.replaceCharactersInRange(rangeOfFirstCharacter, withString: "")

    charactersRemovedFromString += 2

    let rangeOfLastCharacter = NSMakeRange(match.range.location + match.range.length - charactersRemovedFromString, 1)

    attributedText.replaceCharactersInRange(rangeOfLastCharacter, withString: "")
    }

return attributedText
}
Run Code Online (Sandbox Code Playgroud)