import Foundation
let pattern = ##"^(((ht|f)(tp)(s)?(:\/\/))?(([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))(:\d{1,5})?((\/)([\w\.~%-]+))*(\/)?((\?)(([\w]+)(=[\w\.~%-]+)?((&)([\w]+)(=[\w\.~%-]+)?)*)?)?((#)((([\w]+(=[\w\,\*\.~%-]+)?)(&[\w]+(=[\w\,\*\.~%-]+)?)*)|(:~:text=([\w\.~%-]+\,)?([\w\.~%-]+)(\,[\w\.~%-]+){0,2}))?)?)$"##
let regex = try! NSRegularExpression(pattern: pattern, options: .anchorsMatchLines)
let testString = ##"""
//Base case
17hieng.com
17hieng.com.my
www.17hieng.com.my
www.edu.17hieng.com.my
192.168.1.1
//With protocol
http://17hieng.com
https://192.168.1.1
//With Port
http://17hieng.com:8080
https://192.168.1.1:443
//With Path
www.edu.17hieng.com.my/edu
192.168.1.1/edu/
http://17hieng.com/edu/edu
https://192.168.1.1/
//With query
www.edu.17hieng.com.my?query=a&b=c
192.168.1.1/edu/?query=a&b=c@a.com
http://17hieng.com/edu/edu?query=a
https://192.168.1.1/?query=a&b&c=1
//With Fragment
www.edu.17hieng.com.my#about
192.168.1.1/edu?#line=10,20
192.168.1.1/edu/?query=a#t=40,8.0&xywh=160,120,320,240
http://17hieng.com/edu/edu?query=a#:~:text=prefix-,textStart,textEnd,-suffix
https://192.168.1.1/?query=a&b&c=1#
//domain only
17hieng.com
edu.17hieng.com
17hieng.com/
edu.17hieng.com/
//domain + https protocol
https://17hieng.com
https://edu.17hieng.com
https://17hieng.com/
https://edu.17hieng.com/
//domain + http protocol
http://17hieng.com
http://edu.17hieng.com
http://17hieng.com/
http://edu.17hieng.com/
//domain + file path
17hieng.com/cpp
edu.17hieng.com/cpp
17hieng.com/cpp/
edu.17hieng.com/cpp/
//domain + https protocol + file path
https://17hieng.com/cpp
https://edu.17hieng.com/cpp
https://17hieng.com/cpp/
https://edu.17hieng.com/cpp/
//domain + http protocol + file path
http://17hieng.com/cpp
http://edu.17hieng.com/cpp
http://17hieng.com/cpp/
http://edu.17hieng.com/cpp/
//domain + multiple folder file path
17hieng.com/cpp/intro
edu.17hieng.com/cpp/intro
17hieng.com/cpp/intro/
edu.17hieng.com/cpp/intro/
//domain + https protocol + multiple folder file path
https://17hieng.com/cpp/intro
https://edu.17hieng.com/cpp/intro
https://17hieng.com/cpp/intro/
https://edu.17hieng.com/cpp/intro/
//domain + http protocol + multiple folder file path
http://17hieng.com/cpp/intro
http://edu.17hieng.com/cpp/intro
http://17hieng.com/cpp/intro/
http://edu.17hieng.com/cpp/intro/
//domain + ?
17hieng.com?
edu.17hieng.com?
17hieng.com/?
edu.17hieng.com/?
//domain + https protocol + ?
https://17hieng.com?
https://edu.17hieng.com?
https://17hieng.com/?
https://edu.17hieng.com/?
//domain + http protocol + ?
http://17hieng.com?
http://edu.17hieng.com?
http://17hieng.com/?
http://edu.17hieng.com/?
//domain + file path + ?
17hieng.com/cpp?
edu.17hieng.com/cpp?
17hieng.com/cpp/?
edu.17hieng.com/cpp/?
//domain + https protocol + file path + ?
https://17hieng.com/cpp?
https://edu.17hieng.com/cpp?
https://17hieng.com/cpp/?
https://edu.17hieng.com/cpp/?
//domain + http protocol + file path + ?
http://17hieng.com/cpp?
http://edu.17hieng.com/cpp?
http://17hieng.com/cpp/?
http://edu.17hieng.com/cpp/?
//domain + multiple folder file path + ?
17hieng.com/cpp/intro?
edu.17hieng.com/cpp/intro?
17hieng.com/cpp/intro/?
edu.17hieng.com/cpp/intro/?
//domain + https protocol + multiple folder file path + ?
https://17hieng.com/cpp/intro?
https://edu.17hieng.com/cpp/intro?
https://17hieng.com/cpp/intro/?
https://edu.17hieng.com/cpp/intro/?
//domain + http protocol + multiple folder file path + ?
http://17hieng.com/cpp/intro?
http://edu.17hieng.com/cpp/intro?
http://17hieng.com/cpp/intro/?
http://edu.17hieng.com/cpp/intro/?
//domain + parameter
17hieng.com?name
edu.17hieng.com?name
17hieng.com/?name
edu.17hieng.com/?name
//domain + https protocol + parameter
https://17hieng.com?name
https://edu.17hieng.com?name
https://17hieng.com/?name
https://edu.17hieng.com/?name
//domain + http protocol + parameter
http://17hieng.com?name
http://edu.17hieng.com?name
http://17hieng.com/?name
http://edu.17hieng.com/?name
//domain + file path + parameter
17hieng.com/cpp?name
edu.17hieng.com/cpp?name
17hieng.com/cpp/?name
edu.17hieng.com/cpp/?name
//domain + https protocol + file path + parameter
https://17hieng.com/cpp?name
https://edu.17hieng.com/cpp?name
https://17hieng.com/cpp/?name
https://edu.17hieng.com/cpp/?name
//domain + http protocol + file path + parameter
http://17hieng.com/cpp?name
http://edu.17hieng.com/cpp?name
http://17hieng.com/cpp/?name
http://edu.17hieng.com/cpp/?name
//domain + multiple folder file path + parameter
17hieng.com/cpp/intro?name
edu.17hieng.com/cpp/intro?name
17hieng.com/cpp/intro/?name
edu.17hieng.com/cpp/intro/?name
//domain + https protocol + multiple folder file path + parameter
https://17hieng.com/cpp/intro?name
https://edu.17hieng.com/cpp/intro?name
https://17hieng.com/cpp/intro/?name
https://edu.17hieng.com/cpp/intro/?name
//domain + http protocol + multiple folder file path + parameter
http://17hieng.com/cpp/intro?name
http://edu.17hieng.com/cpp/intro?name
http://17hieng.com/cpp/intro/?name
http://edu.17hieng.com/cpp/intro/?name
//domain + parameter
17hieng.com?name=CheeHieng
edu.17hieng.com?name=Chee%20Hieng
17hieng.com/?name=Chee%20Hieng
edu.17hieng.com/?name=Chee%20Hieng
//domain + https protocol + parameter
https://17hieng.com?name=Chee%20Hieng
https://edu.17hieng.com?name=Chee%20Hieng
https://17hieng.com/?name=Chee%20Hieng
https://edu.17hieng.com/?name=Chee%20Hieng
//domain + http protocol + parameter
http://17hieng.com?name=Chee%20Hieng
http://edu.17hieng.com?name=Chee%20Hieng
http://17hieng.com/?name=Chee%20Hieng
http://edu.17hieng.com/?name=Chee%20Hieng
//domain + file path + parameter
17hieng.com/cpp?name=Chee%20Hieng
edu.17hieng.com/cpp?name=Chee%20Hieng
17hieng.com/cpp/?name=Chee%20Hieng
edu.17hieng.com/cpp/?name=Chee%20Hieng
//domain + https protocol + file path + parameter
https://17hieng.com/cpp?name=Chee%20Hieng
https://edu.17hieng.com/cpp?name=Chee%20Hieng
https://17hieng.com/cpp/?name=Chee%20Hieng
https://edu.17hieng.com/cpp/?name=Chee%20Hieng
//domain + http protocol + file path + parameter
http://17hieng.com/cpp?name=Chee%20Hieng
http://edu.17hieng.com/cpp?name=Chee%20Hieng
http://17hieng.com/cpp/?name=Chee%20Hieng
http://edu.17hieng.com/cpp/?name=Chee%20Hieng
//domain + multiple folder file path + parameter
17hieng.com/cpp/intro?name=Chee%20Hieng
edu.17hieng.com/cpp/intro?name=Chee%20Hieng
17hieng.com/cpp/intro/?name=Chee%20Hieng
edu.17hieng.com/cpp/intro/?name=Chee%20Hieng
//domain + https protocol + multiple folder file path + parameter
https://17hieng.com/cpp/intro?name=Chee%20Hieng
https://edu.17hieng.com/cpp/intro?name=Chee%20Hieng
https://17hieng.com/cpp/intro/?name=Chee%20Hieng
https://edu.17hieng.com/cpp/intro/?name=Chee%20Hieng
//domain + http protocol + multiple folder file path + parameter
http://17hieng.com/cpp/intro?name=Chee%20Hieng
http://edu.17hieng.com/cpp/intro?name=Chee%20Hieng
http://17hieng.com/cpp/intro/?name=Chee%20Hieng
http://edu.17hieng.com/cpp/intro/?name=Chee%20Hieng
//domain + mixed-parameter
17hieng.com?name=Chee%20Hieng&age&id=2200282
edu.17hieng.com?name=Chee%20Hieng&age&id=2200282
17hieng.com/?name=Chee%20Hieng&age&id=2200282
edu.17hieng.com/?name=Chee%20Hieng&age&id=2200282
//domain + https protocol + multi-parameter
https://17hieng.com?name=Chee%20Hieng&age&id=2200282
https://edu.17hieng.com?name=Chee%20Hieng&age&id=2200282
https://17hieng.com/?name=Chee%20Hieng&age&id=2200282
https://edu.17hieng.com/?name=Chee%20Hieng&age&id=2200282
//domain + http protocol + multi-parameter
http://17hieng.com?name=Chee%20Hieng&age&id=2200282
http://edu.17hieng.com?name=Chee%20Hieng&age&id=2200282
http://17hieng.com/?name=Chee%20Hieng&age&id=2200282
http://edu.17hieng.com/?name=Chee%20Hieng&age&id=2200282
//domain + file path + multi-parameter
17hieng.com/cpp?name=Chee%20Hieng&age&id=2200282
edu.17hieng.com/cpp?name=Chee%20Hieng&age&id=2200282
17hieng.com/cpp/?name=Chee%20Hieng&age&id=2200282
edu.17hieng.com/cpp/?name=Chee%20Hieng&age&id=2200282
//domain + https protocol + file path + multi-parameter
https://17hieng.com/cpp?name=Chee%20Hieng&age&id=2200282
https://edu.17hieng.com/cpp?name=Chee%20Hieng&age&id=2200282
https://17hieng.com/cpp/?name=Chee%20Hieng&age&id=2200282
https://edu.17hieng.com/cpp/?name=Chee%20Hieng&age&id=2200282
//domain + http protocol + file path + multi-parameter
http://17hieng.com/cpp?name=Chee%20Hieng&age&id=2200282
http://edu.17hieng.com/cpp?name=Chee%20Hieng&age&id=2200282
http://17hieng.com/cpp/?name=Chee%20Hieng&age&id=2200282
http://edu.17hieng.com/cpp/?name=Chee%20Hieng&age&id=2200282
//domain + multiple folder file path + multi-parameter
17hieng.com/cpp/intro?name=Chee%20Hieng&age&id=2200282
edu.17hieng.com/cpp/intro?name=Chee%20Hieng&age&id=2200282
17hieng.com/cpp/intro/?name=Chee%20Hieng&age&id=2200282
edu.17hieng.com/cpp/intro/?name=Chee%20Hieng&age&id=2200282
//domain + https protocol + multiple folder file path + multi-parameter
https://17hieng.com/cpp/intro?name=Chee%20Hieng&age&id=2200282
https://edu.17hieng.com/cpp/intro?name=Chee%20Hieng&age&id=2200282
https://17hieng.com/cpp/intro/?name=Chee%20Hieng&age&id=2200282
https://edu.17hieng.com/cpp/intro/?name=Chee%20Hieng&age&id=2200282
//domain + http protocol + multiple folder file path + parameter
http://17hieng.com/cpp/intro?name=Chee%20Hieng&age&id=2200282
http://edu.17hieng.com/cpp/intro?name=Chee%20Hieng&age&id=2200282
http://17hieng.com/cpp/intro/?name=Chee%20Hieng&age&id=2200282
http://edu.17hieng.com/cpp/intro/?name=Chee%20Hieng&age&id=2200%20282_
//Invalid
htp://17hieng.com
17Hieng.c
http:/17hieng.com
https//17h.my
code.17Hi@ng.com
17hieng.com/?=1
17hineg.com//
17Hieng.com/hello world
17Hieng.com<
17hieng.com/h=1
17Hieng.com=2
17hieng.com/?hi=&version
17hieng.com/?hi=1&version&&
17hieng.com/?hi=1&version&q%20
"""##
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