杨锴
2025-03-11 90dc3329d1973fda691e357cf4523d5c7c67fa1d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// StringProtocolExtensions.swift - Copyright 2024 SwifterSwift
 
import Foundation
 
public extension StringProtocol {
    /// SwifterSwift: The longest common suffix.
    ///
    ///        "Hello world!".commonSuffix(with: "It's cold!") = "ld!"
    ///
    /// - Parameters:
    ///     - Parameter aString: The string with which to compare the receiver.
    ///     - Parameter options: Options for the comparison.
    /// - Returns: The longest common suffix of the receiver and the given String.
    func commonSuffix(with aString: some StringProtocol, options: String.CompareOptions = []) -> String {
        return String(zip(reversed(), aString.reversed())
            .lazy
            .prefix(while: { (lhs: Character, rhs: Character) in
                String(lhs).compare(String(rhs), options: options) == .orderedSame
            })
            .map { (lhs: Character, _: Character) in lhs }
            .reversed())
    }
 
    #if canImport(Foundation)
    /// SwifterSwift: Returns a new string in which all occurrences of a regex pattern in a specified range of the
    /// receiver are replaced by the template.
    /// - Parameters:
    ///   - pattern: Regex pattern to replace.
    ///   - template: The regex template to replace the pattern.
    ///   - options: Options to use when matching the regex. Only .regularExpression, .anchored .and caseInsensitive are
    /// supported.
    ///   - searchRange: The range in the receiver in which to search.
    /// - Returns: A new string in which all occurrences of regex pattern in searchRange of the receiver are replaced by
    /// template.
    func replacingOccurrences(
        ofPattern pattern: some StringProtocol,
        withTemplate template: some StringProtocol,
        options: String.CompareOptions = [.regularExpression],
        range searchRange: Range<Self.Index>? = nil) -> String {
        assert(
            options.isStrictSubset(of: [.regularExpression, .anchored, .caseInsensitive]),
            "Invalid options for regular expression replacement")
        return replacingOccurrences(
            of: pattern,
            with: template,
            options: options.union(.regularExpression),
            range: searchRange)
    }
    #endif
}