-5

I'm trying to mask card number with regex. First 6 and last 2 chars can be shown other should "*".

let cardNumber: String = "5890040000000016"

print("Output: ", cardNumber.mask(regexPattern:"XXXXXXX")) // Output: 589004********16

How can I do that in swift?

Kaan Ozdemir
  • 165
  • 2
  • 9
  • Check this: https://stackoverflow.com/q/46249283/1187415 – Martin R Nov 17 '21 at 13:35
  • 4
    There is no `mask` method and `"XXXXXXX"` is not a "regex pattern" so your code is meaningless. If there is something we are not seeing, show it, please. – matt Nov 17 '21 at 13:54
  • Let me explain @matt. I want mask a card number with regex. I need a regex that can detect between first 6 and last 2 chars. I don't know if there is a regex like that. That's why it's XXXXXX. I'm just wondering. – Kaan Ozdemir Nov 17 '21 at 14:02
  • Already, checked. @MartinR – Kaan Ozdemir Nov 17 '21 at 14:04
  • Yes, you can make a regex that does that. But since this can be done easily without a regex, why do you "need" a regex? Is this just a matter of idle curiosity? And again I ask, what is the meaningless code for? If it has a meaning because you have a defined a `mask(regexPattern:)` method, please show that method. – matt Nov 17 '21 at 14:04
  • No matter. Just curiosity. – Kaan Ozdemir Nov 17 '21 at 14:05

3 Answers3

2

Your question contains 2 important parts:

A regex that matches all characters but first 6 and last 2

let regexPattern = "(?<=.{6}).(?=.*.{2}$)"

and

An extension on the String that takes the regex and masks it:

extension String {

    func masked(matching regexPattern: String, with template: String = "*") throws -> String {
        let regex = try NSRegularExpression(pattern: regexPattern, options: NSRegularExpression.Options.caseInsensitive)
        let range = NSMakeRange(0, count)
        return regex.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: template)
    }
}

Usage:

let cardNumber = "5890040000000016"
let regexPattern = "(?<=.{6}).(?=.*.{2}$)"

print("Output:", try! cardNumber.masked(matching: regexPattern))

Output: 589004********16

Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
1

You can concatenate substrings together:

let cardNumber = "5890040000000016"

let start = cardNumber.startIndex ..< cardNumber.index(cardNumber.startIndex, offsetBy: 6)
let end = cardNumber.index(cardNumber.endIndex, offsetBy: -2) ..< cardNumber.endIndex
let result = cardNumber[start] + Array(repeating: "*", count: cardNumber.count - 8) + cardNumber[end]
print(result)

// Prints: 589004********16
George
  • 25,988
  • 10
  • 79
  • 133
0

Perhaps you're looking for something like this:

let s = "5890040000000016"
let patt = ##"^(\d{6})(.*)(\d{2})$"## // this is your pattern
let reg = try! NSRegularExpression(pattern: patt, options: [])
if let m = reg.firstMatch(in: s, options: [], range: NSRange(s.startIndex..<s.endIndex, in: s)) {
    let r = m.range(at:2)
    let result = s.replacingCharacters(in: Range(r, in:s)!, with: String(repeating: "X", count: r.length))
    print(result) // 589004XXXXXXXX16
}
matt
  • 515,959
  • 87
  • 875
  • 1,141