Issue #840

Used to replace credit card regex 30[0-5]#-######-###L in EasyFake

We can use ? to have non-greedy behavior, or I here use square bracket to fine-tune the expression \{[\d*,]*\d*\} Also, I need to reversed the matches because each replacement makes the next range incorrect

extension String {
    func replacingHash() -> String {
        self
            .map { c in
                guard c == "#" else { return String(c) }
                let number = Int.random(in: 0 ... 9)
                return "\(number)"
            }
            .joined()
    }

    func replacingRegexSquareBrackets() -> String {
        replacingMatches(
            pattern: #"\[\d-\d\]"#,
            replace: Replacer.replaceRegexSquareBrackets
        )
    }

    func replacingRegexCurlyBraces() -> String {
        replacingMatches(
            pattern: #"\{[\d*,]*\d*\}"#,
            replace: Replacer.replaceRegexCurlyBraces
        )
    }

    private func replacingMatches(
        pattern: String,
        replace: (String) -> String?
    ) -> String {
        do {
            let regex = try NSRegularExpression(pattern: pattern, options: [])

            let matches = regex.matches(
                in: self,
                options: [],
                range: NSMakeRange(0, self.count)
            )

            let mutableString = NSMutableString(string: self)
            matches.reversed().forEach { match in
                guard
                    let range = Range(match.range, in: self),
                    let replacement = replace(String(self[range]))
                else { return}

                regex.replaceMatches(
                    in: mutableString,
                    options: .reportCompletion,
                    range: match.range,
                    withTemplate: replacement
                )
            }

            return String(mutableString)
        } catch {
            return self
        }
    }
}

Read more