import Foundation
let pattern = #"\b(?<!\d.)(3[47]\d{2}([ -]?)(?!(\d)\3{5}|123456|234567|345678|424242|545454)\d{6}\2(?!(\d)\4{4})\d{5}|((4\d|5[1-5]|65)\d{2}|6011)([ -]?)(?!(\d)\8{3}|4242|5454|1234|3456|5678|2345|4567)\d{4}\7(?!(\d)\9{3})\d{4}\7\d{4})(\b|\s)(?!.\d\d)"#
let regex = try! NSRegularExpression(pattern: pattern)
let testString = #"""
ALL strings in the first section should match
some 4270446050075048
4270-4460-5007-5048
this:4270 4460 5007 5048.
4270 4460 5007 5048 4/20
4270 4460 5007 5048 what
4270 4460 5007 5048
4270 4460 5007 5048 12/20
5105105105105100
5200828282828210
--- (the following should not match - test numbers)
5454545454545454
4123456789012345
4242424242424242
42704460500750a8
4111111111111111
5111111111111111
5555555555555555
3333333333333333
3111111111111111
--- (the following should NOT match)
4270 4460 5007 5048 1234
4270
4270 4460 5007 504
42811293test123
427044605007504812345083 5095 5179 5157 5219 5187 5095 <--- FALSE POSITIVE (contains valid CC but has lots of exra digits)
this:4270 4460 5007 50482
4270 4460 5007 5048 123
4270 4460 5007 5048 1234
Known False positive (test number):
5535 3545 5455 4444
"""#
let stringRange = NSRange(location: 0, length: testString.utf16.count)
let matches = regex.matches(in: testString, range: stringRange)
var result: [[String]] = []
for match in matches {
var groups: [String] = []
for rangeIndex in 1 ..< match.numberOfRanges {
let nsRange = match.range(at: rangeIndex)
guard !NSEqualRanges(nsRange, NSMakeRange(NSNotFound, 0)) else { continue }
let string = (testString as NSString).substring(with: nsRange)
groups.append(string)
}
if !groups.isEmpty {
result.append(groups)
}
}
print(result)
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for Swift 5.2, please visit: https://developer.apple.com/documentation/foundation/nsregularexpression