如何在Swift中使用NSRange拆分和重建字符串

如何在Swift中使用NSRange拆分和重建字符串,swift,string,nsattributedstring,Swift,String,Nsattributedstring,我使用它的背景渲染功能。现在,我在呈现之前解析字符串,以检查文本内容的出现,例如:正则表达式 这就是我解析文本的方式: private func parseText(_ text: String) -> [NSTextCheckingResult] { let attributedString = NSAttributedString(string: text) let range = NSRange(location: 0, length: text.co

我使用它的背景渲染功能。现在,我在呈现之前解析字符串,以检查文本内容的出现,例如:正则表达式

这就是我解析文本的方式:

private func parseText(_ text: String) -> [NSTextCheckingResult] {
        let attributedString = NSAttributedString(string: text)
        let range = NSRange(location: 0, length: text.count)
        var matches = [NSTextCheckingResult]()

        // Get matches of all .custom DetectorType and add it to matches array
        let regexs = MarkdownAttribute.enabledDetectors
            .filter { $0.isCustom }
            .map { parseForMatches(with: $0, in: attributedString, for: range) }
            .joined()
            matches.append(contentsOf: regexs)

        // Get all Checking Types of detectors, except for .custom because they contain their own regex
        let detectorCheckingTypes = MarkdownAttribute.enabledDetectors
            .filter { !$0.isCustom }
            .reduce(0) { $0 | $1.textCheckingType.rawValue }
        if detectorCheckingTypes > 0, let detector = try? NSDataDetector(types: detectorCheckingTypes) {
            let detectorMatches = detector.matches(in: text, options: [], range: range)
            matches.append(contentsOf: detectorMatches)
        }

        guard MarkdownAttribute.enabledDetectors.contains(.url) else {
            return matches
        }

        // Enumerate NSAttributedString NSLinks and append ranges
        var results: [NSTextCheckingResult] = matches

        attributedString.enumerateAttribute(NSAttributedString.Key.link, in: range, options: []) { value, range, _ in
            guard let url = value as? URL else { return }
            let result = NSTextCheckingResult.linkCheckingResult(range: range, url: url)
            results.append(result)
        }

        return results
    }
StyledTextKit
具有轻松构建
NSAttributedString
的功能。添加带有traits的字符串。或者在字符串中添加特征

所以我现在有一个
[NSTextCheckingResult]
数组。如何使用
NSTextCheckingResult
提供的范围重建?还是我错过了一条更好的路

public enum DetectorType: Hashable {

        case address
        case date
        case phoneNumber
        case url
        case transitInformation
        case custom(NSRegularExpression)

        // swiftlint:disable force_try
        public static var hashtag = DetectorType.custom(try! NSRegularExpression(pattern: "#[a-zA-Z0-9]{4,}", options: []))
        public static var mention = DetectorType.custom(try! NSRegularExpression(pattern: "@[a-zA-Z0-9]{4,}", options: []))
        // swiftlint:enable force_try

        internal var textCheckingType: NSTextCheckingResult.CheckingType {
            switch self {
                case .address: return .address
                case .date: return .date
                case .phoneNumber: return .phoneNumber
                case .url: return .link
                case .transitInformation: return .transitInformation
                case .custom: return .regularExpression
            }
        }

        /// Simply check if the detector type is a .custom
        public var isCustom: Bool {
            switch self {
                case .custom: return true
                default: return false
            }
        }

        ///The hashValue of the `DetectorType` so we can conform to `Hashable` and be sorted.
        public func hash(into: inout Hasher) {
            into.combine(toInt())
        }

        /// Return an 'Int' value for each `DetectorType` type so `DetectorType` can conform to `Hashable`
        private func toInt() -> Int {
            switch self {
                case .address: return 0
                case .date: return 1
                case .phoneNumber: return 2
                case .url: return 3
                case .transitInformation: return 4
                case .custom(let regex): return regex.hashValue
            }
        }

    }
private func parseForMatches(with detector: MarkdownAttribute.DetectorType, in text: NSAttributedString, for range: NSRange) -> [NSTextCheckingResult] {
        switch detector {
            case .custom(let regex):
                return regex.matches(in: text.string, options: [], range: range)
            default:
                fatalError("You must pass a .custom DetectorType")
        }
    }