import Foundation
let pattern = #"""
(?smx)
(?(DEFINE)
(?<jsonObject>
\{(?&jsonField)(?>,(?&jsonField))*+\}|
\{[[:space:]]*+\}
)
(?<jsonArray>
\[(?&jsonValue)(?>,(?&jsonValue))*+\]|
\[[[:space:]]*+\]
)
(?<string>
"
[^"\\]*+
(?>
(?>
\\["\\\/rntfb]|
\\u[[:xdigit:]]{4}
)++
[^"\\]*+
)*+
"
)
(?<number>
\-?+
(?>
[1-9][[:digit:]]*+|
0
)
(?>\.[[:digit:]]++)?+
(?>[eE][\+\-]?+[[:digit:]]++)?+
)
(?<jsonValue>
[[:space:]]*+
(?>
(?&string)|
(?&number)|
(?&jsonObject)|
(?&jsonArray)|
false|
true|
null
)
[[:space:]]*+
)
(?<jsonField>
[[:space:]]*+(?&string)[[:space:]]*+\:
(?&jsonValue)
)
)
^(?&jsonValue),\n
"""#
let regex = try! NSRegularExpression(pattern: pattern)
let testString = ##"""
null,
null,
null ,
null ,
false,
false,
false ,
false ,
true,
true,
true ,
true ,
123,
0,
-123,
-0,
123.0,
0.0,
-123.0,
-0.0,
123e1,
0e1,
-123e1,
-0e1,
123.0e1,
0.0e1,
-123.0e1,
-0.0e1,
123e+1,
0e+1,
-123e+1,
-0e+1,
123.0e+1,
0.0e+1,
-123.0e+1,
-0.0e+1,
123e-1,
0e-1,
-123e-1,
-0e-1,
123.0e-1,
0.0e-1,
-123.0e-1,
-0.0e-1,
123E1,
0E1,
-123E1,
-0E1,
123.0E1,
0.0E1,
-123.0E1,
-0.0E1,
123E+1,
0E+1,
-123E+1,
-0E+1,
123.0E+1,
0.0E+1,
-123.0E+1,
-0.0E+1,
123E-1,
0E-1,
-123E-1,
-0E-1,
123.0E-1,
0.0E-1,
-123.0E-1,
-0.0E-1,
123,
0,
-123,
-0,
123.0,
0.0,
-123.0,
-0.0,
123e1,
0e1,
-123e1,
-0e1,
123.0e1,
0.0e1,
-123.0e1,
-0.0e1,
123e+1,
0e+1,
-123e+1,
-0e+1,
123.0e+1,
0.0e+1,
-123.0e+1,
-0.0e+1,
123e-1,
0e-1,
-123e-1,
-0e-1,
123.0e-1,
0.0e-1,
-123.0e-1,
-0.0e-1,
123E1,
0E1,
-123E1,
-0E1,
123.0E1,
0.0E1,
-123.0E1,
-0.0E1,
123E+1,
0E+1,
-123E+1,
-0E+1,
123.0E+1,
0.0E+1,
-123.0E+1,
-0.0E+1,
123E-1,
0E-1,
-123E-1,
-0E-1,
123.0E-1,
0.0E-1,
-123.0E-1,
-0.0E-1,
123 ,
0 ,
-123 ,
-0 ,
123.0 ,
0.0 ,
-123.0 ,
-0.0 ,
123e1 ,
0e1 ,
-123e1 ,
-0e1 ,
123.0e1 ,
0.0e1 ,
-123.0e1 ,
-0.0e1 ,
123e+1 ,
0e+1 ,
-123e+1 ,
-0e+1 ,
123.0e+1 ,
0.0e+1 ,
-123.0e+1 ,
-0.0e+1 ,
123e-1 ,
0e-1 ,
-123e-1 ,
-0e-1 ,
123.0e-1 ,
0.0e-1 ,
-123.0e-1 ,
-0.0e-1 ,
123E1 ,
0E1 ,
-123E1 ,
-0E1 ,
123.0E1 ,
0.0E1 ,
-123.0E1 ,
-0.0E1 ,
123E+1 ,
0E+1 ,
-123E+1 ,
-0E+1 ,
123.0E+1 ,
0.0E+1 ,
-123.0E+1 ,
-0.0E+1 ,
123E-1 ,
0E-1 ,
-123E-1 ,
-0E-1 ,
123.0E-1 ,
0.0E-1 ,
-123.0E-1 ,
-0.0E-1 ,
123 ,
0 ,
-123 ,
-0 ,
123.0 ,
0.0 ,
-123.0 ,
-0.0 ,
123e1 ,
0e1 ,
-123e1 ,
-0e1 ,
123.0e1 ,
0.0e1 ,
-123.0e1 ,
-0.0e1 ,
123e+1 ,
0e+1 ,
-123e+1 ,
-0e+1 ,
123.0e+1 ,
0.0e+1 ,
-123.0e+1 ,
-0.0e+1 ,
123e-1 ,
0e-1 ,
-123e-1 ,
-0e-1 ,
123.0e-1 ,
0.0e-1 ,
-123.0e-1 ,
-0.0e-1 ,
123E1 ,
0E1 ,
-123E1 ,
-0E1 ,
123.0E1 ,
0.0E1 ,
-123.0E1 ,
-0.0E1 ,
123E+1 ,
0E+1 ,
-123E+1 ,
-0E+1 ,
123.0E+1 ,
0.0E+1 ,
-123.0E+1 ,
-0.0E+1 ,
123E-1 ,
0E-1 ,
-123E-1 ,
-0E-1 ,
123.0E-1 ,
0.0E-1 ,
-123.0E-1 ,
-0.0E-1 ,
"",
"zyxwvuts",
"\\\/\r\n\t\f\b",
"\u1234\uabcd\uABCD",
"zyxwvutszyxwvuts",
"zyxwvuts\\\/\r\n\t\f\b",
"zyxwvuts\u1234\uabcd\uABCD",
"\\\/\r\n\t\f\bzyxwvuts",
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b",
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD",
"\u1234\uabcd\uABCDzyxwvuts",
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b",
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD",
"zyxwvutszyxwvutszyxwvuts",
"zyxwvuts\\\/\r\n\t\f\bzyxwvuts",
"zyxwvuts\u1234\uabcd\uABCDzyxwvuts",
"\\\/\r\n\t\f\bzyxwvutszyxwvuts",
"\\\/\r\n\t\f\b\\\/\r\n\t\f\bzyxwvuts",
"\\\/\r\n\t\f\b\u1234\uabcd\uABCDzyxwvuts",
"\u1234\uabcd\uABCDzyxwvutszyxwvuts",
"\u1234\uabcd\uABCD\\\/\r\n\t\f\bzyxwvuts",
"\u1234\uabcd\uABCD\u1234\uabcd\uABCDzyxwvuts",
"zyxwvutszyxwvuts\\\/\r\n\t\f\b",
"zyxwvuts\\\/\r\n\t\f\b\\\/\r\n\t\f\b",
"zyxwvuts\u1234\uabcd\uABCD\\\/\r\n\t\f\b",
"\\\/\r\n\t\f\bzyxwvuts\\\/\r\n\t\f\b",
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b\\\/\r\n\t\f\b",
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD\\\/\r\n\t\f\b",
"\u1234\uabcd\uABCDzyxwvuts\\\/\r\n\t\f\b",
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b\\\/\r\n\t\f\b",
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD\\\/\r\n\t\f\b",
"zyxwvutszyxwvuts\u1234\uabcd\uABCD",
"zyxwvuts\\\/\r\n\t\f\b\u1234\uabcd\uABCD",
"zyxwvuts\u1234\uabcd\uABCD\u1234\uabcd\uABCD",
"\\\/\r\n\t\f\bzyxwvuts\u1234\uabcd\uABCD",
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b\u1234\uabcd\uABCD",
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD\u1234\uabcd\uABCD",
"\u1234\uabcd\uABCDzyxwvuts\u1234\uabcd\uABCD",
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b\u1234\uabcd\uABCD",
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD\u1234\uabcd\uABCD",
"",
"zyxwvuts",
"\\\/\r\n\t\f\b",
"\u1234\uabcd\uABCD",
"zyxwvutszyxwvuts",
"zyxwvuts\\\/\r\n\t\f\b",
"zyxwvuts\u1234\uabcd\uABCD",
"\\\/\r\n\t\f\bzyxwvuts",
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b",
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD",
"\u1234\uabcd\uABCDzyxwvuts",
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b",
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD",
"zyxwvutszyxwvutszyxwvuts",
"zyxwvuts\\\/\r\n\t\f\bzyxwvuts",
"zyxwvuts\u1234\uabcd\uABCDzyxwvuts",
"\\\/\r\n\t\f\bzyxwvutszyxwvuts",
"\\\/\r\n\t\f\b\\\/\r\n\t\f\bzyxwvuts",
"\\\/\r\n\t\f\b\u1234\uabcd\uABCDzyxwvuts",
"\u1234\uabcd\uABCDzyxwvutszyxwvuts",
"\u1234\uabcd\uABCD\\\/\r\n\t\f\bzyxwvuts",
"\u1234\uabcd\uABCD\u1234\uabcd\uABCDzyxwvuts",
"zyxwvutszyxwvuts\\\/\r\n\t\f\b",
"zyxwvuts\\\/\r\n\t\f\b\\\/\r\n\t\f\b",
"zyxwvuts\u1234\uabcd\uABCD\\\/\r\n\t\f\b",
"\\\/\r\n\t\f\bzyxwvuts\\\/\r\n\t\f\b",
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b\\\/\r\n\t\f\b",
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD\\\/\r\n\t\f\b",
"\u1234\uabcd\uABCDzyxwvuts\\\/\r\n\t\f\b",
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b\\\/\r\n\t\f\b",
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD\\\/\r\n\t\f\b",
"zyxwvutszyxwvuts\u1234\uabcd\uABCD",
"zyxwvuts\\\/\r\n\t\f\b\u1234\uabcd\uABCD",
"zyxwvuts\u1234\uabcd\uABCD\u1234\uabcd\uABCD",
"\\\/\r\n\t\f\bzyxwvuts\u1234\uabcd\uABCD",
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b\u1234\uabcd\uABCD",
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD\u1234\uabcd\uABCD",
"\u1234\uabcd\uABCDzyxwvuts\u1234\uabcd\uABCD",
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b\u1234\uabcd\uABCD",
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD\u1234\uabcd\uABCD",
"" ,
"zyxwvuts" ,
"\\\/\r\n\t\f\b" ,
"\u1234\uabcd\uABCD" ,
"zyxwvutszyxwvuts" ,
"zyxwvuts\\\/\r\n\t\f\b" ,
"zyxwvuts\u1234\uabcd\uABCD" ,
"\\\/\r\n\t\f\bzyxwvuts" ,
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b" ,
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD" ,
"\u1234\uabcd\uABCDzyxwvuts" ,
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b" ,
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD" ,
"zyxwvutszyxwvutszyxwvuts" ,
"zyxwvuts\\\/\r\n\t\f\bzyxwvuts" ,
"zyxwvuts\u1234\uabcd\uABCDzyxwvuts" ,
"\\\/\r\n\t\f\bzyxwvutszyxwvuts" ,
"\\\/\r\n\t\f\b\\\/\r\n\t\f\bzyxwvuts" ,
"\\\/\r\n\t\f\b\u1234\uabcd\uABCDzyxwvuts" ,
"\u1234\uabcd\uABCDzyxwvutszyxwvuts" ,
"\u1234\uabcd\uABCD\\\/\r\n\t\f\bzyxwvuts" ,
"\u1234\uabcd\uABCD\u1234\uabcd\uABCDzyxwvuts" ,
"zyxwvutszyxwvuts\\\/\r\n\t\f\b" ,
"zyxwvuts\\\/\r\n\t\f\b\\\/\r\n\t\f\b" ,
"zyxwvuts\u1234\uabcd\uABCD\\\/\r\n\t\f\b" ,
"\\\/\r\n\t\f\bzyxwvuts\\\/\r\n\t\f\b" ,
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b\\\/\r\n\t\f\b" ,
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD\\\/\r\n\t\f\b" ,
"\u1234\uabcd\uABCDzyxwvuts\\\/\r\n\t\f\b" ,
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b\\\/\r\n\t\f\b" ,
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD\\\/\r\n\t\f\b" ,
"zyxwvutszyxwvuts\u1234\uabcd\uABCD" ,
"zyxwvuts\\\/\r\n\t\f\b\u1234\uabcd\uABCD" ,
"zyxwvuts\u1234\uabcd\uABCD\u1234\uabcd\uABCD" ,
"\\\/\r\n\t\f\bzyxwvuts\u1234\uabcd\uABCD" ,
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b\u1234\uabcd\uABCD" ,
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD\u1234\uabcd\uABCD" ,
"\u1234\uabcd\uABCDzyxwvuts\u1234\uabcd\uABCD" ,
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b\u1234\uabcd\uABCD" ,
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD\u1234\uabcd\uABCD" ,
"" ,
"zyxwvuts" ,
"\\\/\r\n\t\f\b" ,
"\u1234\uabcd\uABCD" ,
"zyxwvutszyxwvuts" ,
"zyxwvuts\\\/\r\n\t\f\b" ,
"zyxwvuts\u1234\uabcd\uABCD" ,
"\\\/\r\n\t\f\bzyxwvuts" ,
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b" ,
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD" ,
"\u1234\uabcd\uABCDzyxwvuts" ,
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b" ,
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD" ,
"zyxwvutszyxwvutszyxwvuts" ,
"zyxwvuts\\\/\r\n\t\f\bzyxwvuts" ,
"zyxwvuts\u1234\uabcd\uABCDzyxwvuts" ,
"\\\/\r\n\t\f\bzyxwvutszyxwvuts" ,
"\\\/\r\n\t\f\b\\\/\r\n\t\f\bzyxwvuts" ,
"\\\/\r\n\t\f\b\u1234\uabcd\uABCDzyxwvuts" ,
"\u1234\uabcd\uABCDzyxwvutszyxwvuts" ,
"\u1234\uabcd\uABCD\\\/\r\n\t\f\bzyxwvuts" ,
"\u1234\uabcd\uABCD\u1234\uabcd\uABCDzyxwvuts" ,
"zyxwvutszyxwvuts\\\/\r\n\t\f\b" ,
"zyxwvuts\\\/\r\n\t\f\b\\\/\r\n\t\f\b" ,
"zyxwvuts\u1234\uabcd\uABCD\\\/\r\n\t\f\b" ,
"\\\/\r\n\t\f\bzyxwvuts\\\/\r\n\t\f\b" ,
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b\\\/\r\n\t\f\b" ,
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD\\\/\r\n\t\f\b" ,
"\u1234\uabcd\uABCDzyxwvuts\\\/\r\n\t\f\b" ,
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b\\\/\r\n\t\f\b" ,
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD\\\/\r\n\t\f\b" ,
"zyxwvutszyxwvuts\u1234\uabcd\uABCD" ,
"zyxwvuts\\\/\r\n\t\f\b\u1234\uabcd\uABCD" ,
"zyxwvuts\u1234\uabcd\uABCD\u1234\uabcd\uABCD" ,
"\\\/\r\n\t\f\bzyxwvuts\u1234\uabcd\uABCD" ,
"\\\/\r\n\t\f\b\\\/\r\n\t\f\b\u1234\uabcd\uABCD" ,
"\\\/\r\n\t\f\b\u1234\uabcd\uABCD\u1234\uabcd\uABCD" ,
"\u1234\uabcd\uABCDzyxwvuts\u1234\uabcd\uABCD" ,
"\u1234\uabcd\uABCD\\\/\r\n\t\f\b\u1234\uabcd\uABCD" ,
"\u1234\uabcd\uABCD\u1234\uabcd\uABCD\u1234\uabcd\uABCD" ,
{},
{ },
{"1":1},
{ "1" : 1 },
{"1":1,"2":2},
{ "1" : 1, "2" : 2 },
{},
{ },
{"1":1},
{ "1" : 1 },
{"1":1,"2":2},
{ "1" : 1, "2" : 2 },
{} ,
{ } ,
{"1":1} ,
{ "1" : 1 } ,
{"1":1,"2":2} ,
{ "1" : 1, "2" : 2 } ,
{} ,
{ } ,
{"1":1} ,
{ "1" : 1 } ,
{"1":1,"2":2} ,
{ "1" : 1, "2" : 2 } ,
[],
[ ],
[1],
[ 1 ],
[1,2],
[ 1, 2 ],
[],
[ ],
[1],
[ 1 ],
[1,2],
[ 1, 2 ],
[] ,
[ ] ,
[1] ,
[ 1 ] ,
[1,2] ,
[ 1, 2 ] ,
[] ,
[ ] ,
[1] ,
[ 1 ] ,
[1,2] ,
[ 1, 2 ] ,
{"x":{}},
{"x":[]},
{ "x" : {} },
{ "x" : [] },
[{}],
[[]],
[ { } ],
[ [ ] ],
{"x":{}},
{"x":[]},
{ "x" : {} },
{ "x" : [] },
[{}],
[[]],
[ { } ],
[ [ ] ],
{"x":{}} ,
{"x":[]} ,
{ "x" : {} } ,
{ "x" : [] } ,
[{}] ,
[[]] ,
[ { } ] ,
[ [ ] ] ,
{"x":{}} ,
{"x":[]} ,
{ "x" : {} } ,
{ "x" : [] } ,
[{}] ,
[[]] ,
[ { } ] ,
[ [ ] ] ,
#values to NOT match
Null,
False,
True,
01,
+1,
1.,
" " ",
" \ ",
" \x ",
""x,
"""##
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