我需要帮助在格式化字符串后删除下划线

I need help removing underscore after formatting a string

当字符串以下划线开头和结尾时,我将该字符串设为斜体。之后,我将删除下划线。如果字符串是这样的 "_hello_ world"

但是,这不起作用=> "_hello_ world _happy_"

这是我的正则表达式 => "\_(.*?)\_"

func applyItalicFormat(string: String) {
        let matches = RegexPattern.italicRegex.matches(string)
        for match in matches {
            let mRange = match.range
            self.addAttributes([NSAttributedStringKey.font : UIFont.latoMediumItalic(size: 15)],
                               range: mRange)

            if let rangeObj = Range(NSMakeRange(mRange.location, mRange.upperBound), in: string) {
                var sub = string.substring(with: rangeObj)
                sub = sub.replacingOccurrences(of: "_", with: "")

                print("sub is \(sub)")

                replaceCharacters(in: mRange, with: sub)
            } else {

            }
        }
    }

稍作修改,并使用 range(at:) 个匹配项:

extension NSMutableAttributedString {
    func applyItalicFormat(pattern: String) {
        let regex = try! NSRegularExpression(pattern: pattern, options: [])
        let matches = regex.matches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count))
        let italicAttributes = [NSAttributedString.Key.font: UIFont.italicSystemFont(ofSize: 15)]
        for match in matches.reversed() {
            let textRange = match.range(at: 1)
            let attributedTextToChange = NSMutableAttributedString(attributedString: self.attributedSubstring(from: textRange))
            attributedTextToChange.addAttributes(italicAttributes, range: NSRange(location: 0, length: attributedTextToChange.length))
            replaceCharacters(in: match.range, with: attributedTextToChange)
        }
    }
}

您不需要替换 _,您已经有了没有下划线的良好文本范围。
我使用 matches.reversed(),因为当您应用第一个时,已经找到的第二个范围不再正确(您删除了两次 _)。
我比较喜欢把attributedString部分抽出来修改,修改,然后用修改后的替换。 我简化了一些其余的代码。

示例测试(可在 Playground 中使用):

let initialTexts = ["_hello_ world", "\n\n", "_hello_ world _happy_"]
let label = UILabel.init(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
label.backgroundColor = .orange
label.numberOfLines = 0

let attr = NSMutableAttributedString()

for anInitialText in initialTexts {
    let attributedStr = NSMutableAttributedString(string: anInitialText)
    attributedStr.applyItalicFormat(pattern: "\_(.*?)\_")
    attr.append(attributedStr)
}

label.attributedText = attr

另一种 Regex 格式,\_(?:(?!_).)+\_ 并使用 map

var mySentence = "This is from _mcdonal_ mac _system_ which says that _below_ answer is one of the _easiest_ way"
var wholeText = NSMutableAttributedString()

override func viewDidLoad() {
    super.viewDidLoad()

    wholeText = NSMutableAttributedString(string: mySentence)
    italicLbl.attributedText = matches(for: "\_(?:(?!_).)+\_", in: mySentence)
}


func matches(for regex: String, in text: String) -> NSAttributedString {

    do {
        let regex = try NSRegularExpression(pattern: regex)
        let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text))
        let _ = results.map { (val) in

            wholeText.addAttributes([NSAttributedString.Key.font : UIFont.italicSystemFont(ofSize: 17)],
                                    range: val.range)
            var sub = String(text[Range(val.range, in: text)!])
            sub = sub.replacingOccurrences(of: "_", with: " ")

            wholeText.replaceCharacters(in: val.range, with: sub)
        }
        return wholeText

    } catch let error {
        print("invalid regex: \(error.localizedDescription)")
        return wholeText
    }
}

截图