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

String 更改属性字符串的文本并在Swift中保留属性,string,swift,nsmutablestring,string-substitution,String,Swift,Nsmutablestring,String Substitution,对于数据库程序中的输出,我有一些文本,我插入了一些标记来表示粗体或斜体,还有一些文本可以代替图像。例如: “%Important%^所有员工到休息室^”的最终输出应为: 重要所有员工到休息室 我编写了代码来查找周围带有“%”符号和“^”符号的文本,但现在的问题是文本输出如下: %重要%^所有员工请到休息室^ 我想删除这些%和^,同时保留字符串的格式 这是我一直在使用的代码,直到它崩溃: func processText(inString string: String) -> NSAttri

对于数据库程序中的输出,我有一些文本,我插入了一些标记来表示粗体或斜体,还有一些文本可以代替图像。例如:

“%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
}
func processText(指令字符串:字符串)->NSAttribute字符串{

让pattern=[”(?这里有一个可能的解决方案,本质上是 从Objective-C到Swift

其思想是在一个循环中添加属性并删除分隔符 删除第一个分隔符后,需要使用变量来调整匹配范围

为了简单起见,仅显示“^…^”处理

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

    let pattern = "(\\^)(.*?)(\\^)"

    let regex = NSRegularExpression(pattern: pattern, options: nil, error: nil)!
    var shift = 0 // number of characters removed so far
    let attributedText = NSMutableAttributedString(string: string)
    regex.enumerateMatchesInString(string, options: nil, range: NSMakeRange(0, count(string.utf16))) {
        (result, _, _) -> Void in
        var r1 = result.rangeAtIndex(1) // Location of the leading delimiter
        var r2 = result.rangeAtIndex(2) // Location of the string between the delimiters
        var r3 = result.rangeAtIndex(3) // Location of the trailing delimiter
        // Adjust locations according to the string modifications:
        r1.location -= shift
        r2.location -= shift
        r3.location -= shift
        // Set attribute for string between delimiters:
        attributedText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Oblique", size: 14.0)!, range: r2)
        // Remove leading and trailing delimiters:
        attributedText.mutableString.deleteCharactersInRange(r3)
        attributedText.mutableString.deleteCharactersInRange(r1)
        // Update offset:
        shift += r1.length + r3.length
    }

    return attributedText.copy() as! NSAttributedString
}
请注意,
EnumerateMatchesInstalling()
采用
NSRange
,因此必须计算 UTF-16字符数,而不是Swift字符数

例如:

let text = "Martin,

I ended up using something very similar, but I decided to change the regular expression to include the ^ marks. In doing so, I was able to then clip the first and last characters of the included attributed substring with the "replaceCharactersInRange" method. This works a little better for my purposes so far because it's working from the attributed string so it doesn't screw up or remove any of its attributes.

I've attached the regex and the portion of the code that deals with italics for anyone's future reference (and thanks, again!):

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
}
let text=“Martin

我最终使用了非常类似的东西,但我决定将正则表达式更改为包含^marks。这样,我就可以使用“replaceCharactersRange”剪裁包含属性子字符串的第一个和最后一个字符到目前为止,这对我来说效果更好一些,因为它是从属性字符串开始工作的,所以它不会搞砸或删除它的任何属性

我已经附上了正则表达式和处理斜体字的代码部分,供大家将来参考(再次感谢!)

这对我有用

扩展UILabel{ func updateAttributedText(text:String){ 如果让attributedText=attributedText{ 让mutableAttributedText=NSMutableAttributedString(attributedString:attributedText) MutableAttributeText.mutableString.setString(文本) self.attributedText=mutableAttributedText } } }
谢谢您的帮助。我会尽快尝试。我确实看到过一些obj-c版本,但我只是在学习Swift,所以objective-c代码翻译不是我自己能做到的。这很奇怪,但有一半时间,此代码返回“执行被中断,原因:EXC\u坏访问(代码=1…)有一半的时间是有效的。有什么原因会如此不稳定吗?@DanM:没有。你有一个输入字符串崩溃的具体例子吗?是的,当我测试字符串“^We's flying!^^^ We's flying!^”它一半时间崩溃,一半时间正确返回字符串。我目前只是在操场上玩它,所以当我使用println(processText(inString:“^We's flying!^^^^^ We's flying!^”)并通过删除最后一个圆括号并将其放回,强制它重新计算字符串时,它的计算结果会有所不同。