package regex import ( "fmt" "slices" "testing" ) var reTests = []struct { re string flags []ReFlag str string result []Group // Stores all zero-groups in the match }{ {"a", nil, "abc", []Group{{0, 1}}}, {"a", nil, "bca", []Group{{2, 3}}}, {"l", nil, "ggllgg", []Group{{2, 3}, {3, 4}}}, {"(b|c)", nil, "abdceb", []Group{{1, 2}, {3, 4}, {5, 6}}}, {"a+", nil, "brerereraaaaabbbbb", []Group{{8, 13}}}, {"ab+", nil, "qweqweqweaqweqweabbbbbr", []Group{{16, 22}}}, {"(b|c|A)", nil, "ooaoobocA", []Group{{5, 6}, {7, 8}, {8, 9}}}, {"ab*", nil, "a", []Group{{0, 1}}}, {"ab*", nil, "abb", []Group{{0, 3}}}, {"a*b", nil, "aaab", []Group{{0, 4}}}, {"a*b", nil, "qwqw", []Group{}}, {"(abc)*", nil, "abcabcabc", []Group{{0, 9}, {9, 9}}}, {"((abc)|(def))*", nil, "abcdef", []Group{{0, 6}, {6, 6}}}, {"(abc)*|(def)*", nil, "abcdef", []Group{{0, 3}, {3, 6}, {6, 6}}}, {"b*a*a", nil, "bba", []Group{{0, 3}}}, {"(ab)+", nil, "abcabddd", []Group{{0, 2}, {3, 5}}}, {"a(b(c|d)*)*", nil, "abccbd", []Group{{0, 6}}}, {"a(b|c)*d+", nil, "abccdd", []Group{{0, 6}}}, {"a*", nil, "", []Group{{0, 0}}}, {"a|b", nil, "c", []Group{}}, {"(a|b)*c", nil, "aabbc", []Group{{0, 5}}}, {"a(b|b)", nil, "ab", []Group{{0, 2}}}, {"a*", nil, "aaaaaaaa", []Group{{0, 8}, {8, 8}}}, {"ab?", nil, "ab", []Group{{0, 2}}}, {"a?b", nil, "ab", []Group{{0, 2}}}, {"a?", nil, "", []Group{{0, 0}}}, {"a?b?c", nil, "a", []Group{}}, {"a?b?c?", nil, "ab", []Group{{0, 2}, {2, 2}}}, {"a?b?c?", nil, "ac", []Group{{0, 2}, {2, 2}}}, {"a?b?c", nil, "abc", []Group{{0, 3}}}, {"a?b?c", nil, "acb", []Group{{0, 2}}}, {"[abc]", nil, "defadefbdefce", []Group{{3, 4}, {7, 8}, {11, 12}}}, {"[ab]c", nil, "ab", []Group{}}, {"g[ab]c", nil, "gac", []Group{{0, 3}}}, {"g[ab]c", nil, "gbc", []Group{{0, 3}}}, {"g[ab]c", nil, "gc", []Group{}}, {"g[ab]c", nil, "gfc", []Group{}}, {"[ab]*", nil, "aabbbabaababab", []Group{{0, 14}, {14, 14}}}, {"[ab]+", nil, "aabbbablaababab", []Group{{0, 7}, {8, 15}}}, {"[Ff]r[Uu]it", nil, "fruit", []Group{{0, 5}}}, {"[Ff]r[Uu]it", nil, "FrUit", []Group{{0, 5}}}, {"[Ff]r[Uu|]it", nil, "Fr|it", []Group{{0, 5}}}, {"[Ff]r([Uu]|[pP])it", nil, "Frpit", []Group{{0, 5}}}, {"[Ff]r[Uu]|[pP]it", nil, "Frpit", []Group{{2, 5}}}, {"[a-zA-Z]+", nil, "Hello, how is it going?", []Group{{0, 5}, {7, 10}, {11, 13}, {14, 16}, {17, 22}}}, {".+", nil, "Hello, how is it going?", []Group{{0, 23}}}, {"a.", nil, "a ", []Group{{0, 2}}}, {"a.b", nil, "a/b", []Group{{0, 3}}}, {".", nil, "a ", []Group{{0, 1}, {1, 2}}}, {"a.", nil, "a ", []Group{{0, 2}}}, {".+b", nil, "abc", []Group{{0, 2}}}, {`\d`, nil, "1a0a3s'''34343s", []Group{{0, 1}, {2, 3}, {4, 5}, {9, 10}, {10, 11}, {11, 12}, {12, 13}, {13, 14}}}, {`\\`, nil, `a\b\c\qwe\`, []Group{{1, 2}, {3, 4}, {5, 6}, {9, 10}}}, {`\W`, nil, `"Hello", he said. How are you doing?`, []Group{{0, 1}, {6, 7}, {7, 8}, {8, 9}, {11, 12}, {16, 17}, {17, 18}, {21, 22}, {25, 26}, {29, 30}, {35, 36}}}, {`\w`, nil, ";';';';';'qwe12", []Group{{10, 11}, {11, 12}, {12, 13}, {13, 14}, {14, 15}}}, {`\s`, nil, "a b c d", []Group{{1, 2}, {3, 4}, {5, 6}, {6, 7}}}, {`\<`, nil, "", []Group{{0, 1}, {6, 7}}}, {`\(.+\)`, nil, "Not (paranthesized), (so) is (this) not", []Group{{4, 35}}}, {"[^abc]+", nil, "qarbtopsaplpclkpasdmb prejip0r,p", []Group{{0, 1}, {2, 3}, {4, 8}, {9, 12}, {13, 16}, {17, 20}, {21, 32}}}, {"[^a]+", nil, "qqqaq", []Group{{0, 3}, {4, 5}}}, {"[^0-9]+", nil, "a1b2c3dd", []Group{{0, 1}, {2, 3}, {4, 5}, {6, 8}}}, {"[^abc]+", nil, "ababababbababaccacacacaca", []Group{}}, {`\[`, nil, "a[b[c[]]]", []Group{{1, 2}, {3, 4}, {5, 6}}}, {`\([^)]+\)`, nil, "Not (paranthesized), (so) is (this) not", []Group{{4, 19}, {21, 25}, {29, 35}}}, {"^ab", nil, "ab bab", []Group{{0, 2}}}, {"^aaaa^", nil, "aaaaaaaa", []Group{}}, {"^([bB][Gg])", nil, "bG", []Group{{0, 2}}}, {"b$", nil, "ba", []Group{}}, {"(boy|girl)$", nil, "girlf", []Group{}}, {`\bint\b`, nil, "print int integer", []Group{{6, 9}}}, {`int\b`, nil, "ints", []Group{}}, {`int(\b|a)`, nil, "inta", []Group{{0, 4}}}, {`\b\d+\b`, nil, "511 a3 43", []Group{{0, 3}, {7, 9}}}, {`\Bint\B`, nil, "prints int integer print", []Group{{2, 5}}}, {`^`, nil, "5^3^2", []Group{{0, 0}}}, {`\^`, nil, "5^3^2", []Group{{1, 2}, {3, 4}}}, {`pool$`, nil, "pool carpool", []Group{{8, 12}}}, {`^int$`, nil, "print int integer", []Group{}}, {`^int$`, nil, "int", []Group{{0, 3}}}, {`b*`, nil, "aaaaaaaaaaqweqwe", []Group{{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {7, 7}, {8, 8}, {9, 9}, {10, 10}, {11, 11}, {12, 12}, {13, 13}, {14, 14}, {15, 15}, {16, 16}}}, {"a{4}", nil, "aabaaa", []Group{}}, {"ab{5}", nil, "abbbbbab", []Group{{0, 6}}}, {"(a|b){3,4}", nil, "aba", []Group{{0, 3}}}, {"(a|b){3,4}", nil, "ababaa", []Group{{0, 4}}}, {"(bc){5,}", nil, "bcbcbcbcbcbcbcbc", []Group{{0, 16}}}, {`\d{3,4}`, nil, "1209", []Group{{0, 4}}}, {`\d{3,4}`, nil, "109", []Group{{0, 3}}}, {`\d{3,4}`, nil, "5", []Group{}}, {`\d{3,4}`, nil, "123135", []Group{{0, 4}}}, {`\d{3,4}`, nil, "89a-0", []Group{}}, {`\d{3,4}`, nil, "ababab555", []Group{{6, 9}}}, {`\bpaint\b`, nil, "paints", []Group{}}, {`\b\w{5}\b`, nil, "paint", []Group{{0, 5}}}, {`[^\w]`, nil, "abcdef1230[]qq';;'", []Group{{10, 11}, {11, 12}, {14, 15}, {15, 16}, {16, 17}, {17, 18}}}, {`[^\W]`, nil, "abcdef1230[]qq';;'", []Group{{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10}, {12, 13}, {13, 14}}}, {`[\[\]]`, nil, "a[b[l]]", []Group{{1, 2}, {3, 4}, {5, 6}, {6, 7}}}, // Unicode tests {`.+`, nil, "úïäö´«åæïëòöê»éãçâï«úïòíñ", []Group{{0, 25}}}, {`a.b`, nil, "a²b", []Group{{0, 3}}}, {`[^a]+`, nil, "úïäö´«åæïëòöê»éãçâï«úïòíñ", []Group{{0, 25}}}, // Fun experiment - AI-generated tests {"(abc|def|ghi)", nil, "abcdefg", []Group{{0, 3}, {3, 6}}}, {"a(b|c)d", nil, "abcd", []Group{}}, {"a(b|c)*d", nil, "abcbcd", []Group{{0, 6}}}, {"a(b|c)+d", nil, "abcbcd", []Group{{0, 6}}}, {"a(b|c)?d", nil, "abd", []Group{{0, 3}}}, {".+", nil, "hello world", []Group{{0, 11}}}, {"a.b", nil, "aXb", []Group{{0, 3}}}, {"a.*b", nil, "aXb", []Group{{0, 3}}}, {"a.{2,3}b", nil, "aXXb", []Group{{0, 4}}}, {"a.{2,}b", nil, "aXXXb", []Group{{0, 5}}}, {"a.{0,3}b", nil, "ab", []Group{{0, 2}}}, {"[abc]+", nil, "abcabc", []Group{{0, 6}}}, {"[a-zA-Z]+", nil, "HelloWorld", []Group{{0, 10}}}, {"[^abc]+", nil, "defghi", []Group{{0, 6}}}, {"^hello", nil, "hello world", []Group{{0, 5}}}, {"world$", nil, "hello world", []Group{{6, 11}}}, {`\bhello\b`, nil, "hello world", []Group{{0, 5}}}, {`\Bhello\B`, nil, "hello world", []Group{}}, {"(hello|world)", nil, "hello world", []Group{{0, 5}, {6, 11}}}, {"(hello|world)+", nil, "hello world", []Group{{0, 5}, {6, 11}}}, {"(hello|world)*", nil, "hello world", []Group{{0, 5}, {5, 5}, {6, 11}, {11, 11}}}, {"(hello|world)?", nil, "hello world", []Group{{0, 5}, {5, 5}, {6, 11}, {11, 11}}}, {"ú.+ï", nil, "úïäö´«åæïëòöê»éãçâï«úïòíñ", []Group{{0, 22}}}, {"(?=hello)", nil, "hello world", []Group{{0, 0}}}, {"(?!hello)", nil, "hello world", []Group{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {7, 7}, {8, 8}, {9, 9}, {10, 10}, {11, 11}}}, {"(?<=hello)", nil, "hello world", []Group{{5, 5}}}, {"(?]*b`, nil, `a>b`, []Group{}}, {`^a*$`, nil, `foo`, []Group{}}, // Out-of-bounds for character classes {`[b-e]`, nil, `a`, []Group{}}, {`[b-e]`, nil, `f`, []Group{}}, {`*?`, nil, `-`, nil}, {`a*?`, nil, `-`, nil}, // non-greedy operators are not supported // Numeric range tests - this is a feature that I added, and doesn't exist // in any other mainstream regex engine {`<0-255>`, nil, `0`, []Group{{0, 1}}}, {`<0-255>`, nil, `7`, []Group{{0, 1}}}, {`<0-255>`, nil, `46`, []Group{{0, 2}}}, {`<0-255>`, nil, `90`, []Group{{0, 2}}}, {`<0-255>`, nil, `107`, []Group{{0, 3}}}, {`<0-255>`, nil, `198`, []Group{{0, 3}}}, {`<0-255>`, nil, `254`, []Group{{0, 3}}}, {`<0-255>`, nil, `255`, []Group{{0, 3}}}, {`<0-255>`, nil, `256`, []Group{{0, 2}, {2, 3}}}, {`^<0-255>$`, nil, `256`, []Group{}}, {`^<0-299792458>$`, nil, `299000999`, []Group{{0, 9}}}, {`^<0-299792458>$`, nil, `299792531`, []Group{}}, {`^<3-0>$`, nil, `-`, nil}, {`^<0-0>$`, nil, `0`, []Group{{0, 1}}}, {`2<0-55>`, nil, `231`, []Group{{0, 3}}}, {`2<0-55>`, nil, `271`, []Group{{0, 2}}}, {`^2<0-55>$`, nil, `271`, []Group{}}, {`<389`, nil, `-`, nil}, {`<389>`, nil, `-`, nil}, {`<-389>`, nil, `-`, nil}, {`<389->`, nil, `-`, nil}, {`<389-400`, nil, `-`, nil}, {`<389-400>`, nil, `391`, []Group{{0, 3}}}, {`\b<1-10000>\b`, nil, `America declared independence in 1776.`, []Group{{33, 37}}}, } var groupTests = []struct { re string flags []ReFlag str string result []Match }{ {"(a)(b)", nil, "ab", []Match{[]Group{{0, 2}, {0, 1}, {1, 2}}}}, {"((a))(b)", nil, "ab", []Match{[]Group{{0, 2}, {0, 1}, {0, 1}, {1, 2}}}}, {"(0)", nil, "ab", []Match{[]Group{}}}, {"(a)b", nil, "ab", []Match{[]Group{{0, 2}, {0, 1}}}}, {"a(b)", nil, "ab", []Match{[]Group{{0, 2}, {1, 2}}}}, {"(a|b)", nil, "ab", []Match{[]Group{{0, 1}, {0, 1}}, []Group{{1, 2}, {1, 2}}}}, {"(a)|(b)", nil, "ab", []Match{[]Group{{0, 1}, {0, 1}, {-1, -1}}, []Group{{1, 2}, {-1, -1}, {1, 2}}}}, {"(a+)(a)", nil, "aaaa", []Match{[]Group{{0, 4}, {0, 3}, {3, 4}}}}, {"(a+)|(a)", nil, "aaaa", []Match{[]Group{{0, 4}, {0, 4}, {-1, -1}}}}, {"(a+)(aa)", nil, "aaaa", []Match{[]Group{{0, 4}, {0, 2}, {2, 4}}}}, {"(aaaa)|(aaaa)", nil, "aaaa", []Match{[]Group{{0, 4}, {0, 4}, {-1, -1}}}}, {"(aaa)|(aaaa)", nil, "aaaa", []Match{[]Group{{0, 4}, {-1, -1}, {0, 4}}}}, {"(aaa)|(aaaa)", nil, "aaaa", []Match{[]Group{{0, 4}, {-1, -1}, {0, 4}}}}, {"(aaaa)|(aaa)", nil, "aaaa", []Match{[]Group{{0, 4}, {0, 4}, {-1, -1}}}}, {"(a)|(aa)", nil, "aa", []Match{[]Group{{0, 2}, {-1, -1}, {0, 2}}}}, {"(a?)a?", nil, "b", []Match{[]Group{{0, 0}, {0, 0}}, []Group{{1, 1}, {1, 1}}}}, {"(a?)a?", nil, "ab", []Match{[]Group{{0, 1}, {0, 1}}, []Group{{1, 1}, {1, 1}}, []Group{{2, 2}, {2, 2}}}}, {"(a?)a?", nil, "aa", []Match{[]Group{{0, 2}, {0, 1}}, []Group{{2, 2}, {2, 2}}}}, {"a((b.d){3})", nil, "abfdbhdbid", []Match{[]Group{{0, 10}, {1, 10}, {7, 10}}}}, // Test cases from Python's RE test suite {`(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\071`, nil, `abcdefghijkl9`, []Match{[]Group{{0, 13}, {0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10}, {10, 11}, {11, 12}}}}, {`()ef`, nil, `def`, []Match{[]Group{{1, 3}, {1, 1}}}}, {`(?:)ef`, nil, `def`, []Match{[]Group{{1, 3}}}}, {`(?:)`, nil, `def`, []Match{[]Group{{0, 0}}, []Group{{1, 1}}, []Group{{2, 2}}, []Group{{3, 3}}}}, {`((a))`, nil, `abc`, []Match{[]Group{{0, 1}, {0, 1}, {0, 1}}}}, {`(a)b(c)`, nil, `abc`, []Match{[]Group{{0, 3}, {0, 1}, {2, 3}}}}, {`(a+|b)*`, nil, `ab`, []Match{[]Group{{0, 2}, {1, 2}}, []Group{{2, 2}}}}, {`(a+|b){0,}`, nil, `ab`, []Match{[]Group{{0, 2}, {1, 2}}, []Group{{2, 2}}}}, {`(a+|b)+`, nil, `ab`, []Match{[]Group{{0, 2}, {1, 2}}}}, {`(a+|b){1,}`, nil, `ab`, []Match{[]Group{{0, 2}, {1, 2}}}}, {`(a+|b)?`, nil, `ab`, []Match{[]Group{{0, 1}, {0, 1}}, []Group{{1, 2}, {1, 2}}, []Group{{2, 2}}}}, {`(a+|b){0,1}`, nil, `ab`, []Match{[]Group{{0, 1}, {0, 1}}, []Group{{1, 2}, {1, 2}}, []Group{{2, 2}}}}, {`(a|b|c|d|e)f`, nil, `ef`, []Match{[]Group{{0, 2}, {0, 1}}}}, {`(ab|cd)e`, nil, `abcde`, []Match{[]Group{{2, 5}, {2, 4}}}}, {`^(ab|cd)e`, nil, `abcde`, []Match{}}, {`(abc|)ef`, nil, `abcdef`, []Match{[]Group{{4, 6}, {4, 4}}}}, {`(a|b)c*d`, nil, `abcd`, []Match{[]Group{{1, 4}, {1, 2}}}}, {`(ab|ab*)bc`, nil, `abc`, []Match{[]Group{{0, 3}, {0, 1}}}}, {`a([bc]*)c*`, nil, `abc`, []Match{[]Group{{0, 3}, {1, 3}}}}, {`a([bc]*)(c*d)`, nil, `abcd`, []Match{[]Group{{0, 4}, {1, 3}, {3, 4}}}}, {`a([bc]+)(c*d)`, nil, `abcd`, []Match{[]Group{{0, 4}, {1, 3}, {3, 4}}}}, {`a([bc]*)(c+d)`, nil, `abcd`, []Match{[]Group{{0, 4}, {1, 2}, {2, 4}}}}, {`(ab|a)b*c`, nil, `abc`, []Match{[]Group{{0, 3}, {0, 2}}}}, {`((a)(b)c)(d)`, nil, `abcd`, []Match{[]Group{{0, 4}, {0, 3}, {0, 1}, {1, 2}, {3, 4}}}}, {`^a(bc+|b[eh])g|.h$`, nil, `abh`, []Match{[]Group{{1, 3}}}}, {`(bc+d$|ef*g.|h?i(j|k))`, nil, `effgz`, []Match{[]Group{{0, 5}, {0, 5}}}}, {`(bc+d$|ef*g.|h?i(j|k))`, nil, `ij`, []Match{[]Group{{0, 2}, {0, 2}, {1, 2}}}}, {`(bc+d$|ef*g.|h?i(j|k))`, nil, `effg`, []Match{}}, {`(bc+d$|ef*g.|h?i(j|k))`, nil, `bcdd`, []Match{}}, {`(bc+d$|ef*g.|h?i(j|k))`, nil, `reffgz`, []Match{[]Group{{1, 6}, {1, 6}}}}, {`(((((((((a)))))))))`, nil, `a`, []Match{[]Group{{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}}}}, {`(((((((((a)))))))))\41`, nil, `a`, []Match{[]Group{{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}}}}, {`(.*)c(.*)`, nil, `abcde`, []Match{[]Group{{0, 5}, {0, 2}, {3, 5}}}}, {`\((.*), (.*)\)`, nil, `(a, b)`, []Match{[]Group{{0, 6}, {1, 2}, {4, 5}}}}, // At this point, the python test suite has a bunch // of backreference tests. Since my engine doesn't // implement backreferences, I've skipped those tests. {`(a)(b)c|ab`, nil, `ab`, []Match{[]Group{{0, 2}}}}, {`(a)+x`, nil, `aaax`, []Match{[]Group{{0, 4}, {2, 3}}}}, {`([ac])+x`, nil, `aacx`, []Match{[]Group{{0, 4}, {2, 3}}}}, {`([^/]*/)*sub1/`, nil, `d:msgs/tdir/sub1/trial/away.cpp`, []Match{[]Group{{0, 17}, {7, 12}}}}, {`([^.]*)\.([^:]*):[T ]+(.*)`, nil, `track1.title:TBlah blah blah`, []Match{[]Group{{0, 28}, {0, 6}, {7, 12}, {14, 28}}}}, {`([^N]*N)+`, nil, `abNNxyzN`, []Match{[]Group{{0, 8}, {4, 8}}}}, {`([^N]*N)+`, nil, `abNNxyz`, []Match{[]Group{{0, 4}, {3, 4}}}}, {`([abc]*)x`, nil, `abcx`, []Match{[]Group{{0, 4}, {0, 3}}}}, {`([abc]*)x`, nil, `abc`, []Match{}}, {`([xyz]*)x`, nil, `abcx`, []Match{[]Group{{3, 4}, {3, 3}}}}, {`(a)+b|aac`, nil, `aac`, []Match{[]Group{{0, 3}}}}, {`([abc])*d`, nil, `abbbcd`, []Match{[]Group{{0, 6}, {4, 5}}}}, {`([abc])*bcd`, nil, `abcd`, []Match{[]Group{{0, 4}, {0, 1}}}}, {`^(ab|cd)e`, nil, `abcde`, []Match{}}, // Case-insensitive tests {`(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\071`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCDEFGHIJKL9`, []Match{[]Group{{0, 13}, {0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10}, {10, 11}, {11, 12}}}}, {`()ef`, []ReFlag{RE_CASE_INSENSITIVE}, `DEF`, []Match{[]Group{{1, 3}, {1, 1}}}}, {`(?:)ef`, []ReFlag{RE_CASE_INSENSITIVE}, `DEF`, []Match{[]Group{{1, 3}}}}, {`(?:)`, []ReFlag{RE_CASE_INSENSITIVE}, `DEF`, []Match{[]Group{{0, 0}}, []Group{{1, 1}}, []Group{{2, 2}}, []Group{{3, 3}}}}, {`((a))`, []ReFlag{RE_CASE_INSENSITIVE}, `ABC`, []Match{[]Group{{0, 1}, {0, 1}, {0, 1}}}}, {`(a)b(c)`, []ReFlag{RE_CASE_INSENSITIVE}, `ABC`, []Match{[]Group{{0, 3}, {0, 1}, {2, 3}}}}, {`(a+|b)*`, []ReFlag{RE_CASE_INSENSITIVE}, `AB`, []Match{[]Group{{0, 2}, {1, 2}}, []Group{{2, 2}}}}, {`(a+|b){0,}`, []ReFlag{RE_CASE_INSENSITIVE}, `AB`, []Match{[]Group{{0, 2}, {1, 2}}, []Group{{2, 2}}}}, {`(a+|b)+`, []ReFlag{RE_CASE_INSENSITIVE}, `AB`, []Match{[]Group{{0, 2}, {1, 2}}}}, {`(a+|b){1,}`, []ReFlag{RE_CASE_INSENSITIVE}, `AB`, []Match{[]Group{{0, 2}, {1, 2}}}}, {`(a+|b)?`, []ReFlag{RE_CASE_INSENSITIVE}, `AB`, []Match{[]Group{{0, 1}, {0, 1}}, []Group{{1, 2}, {1, 2}}, []Group{{2, 2}}}}, {`(a+|b){0,1}`, []ReFlag{RE_CASE_INSENSITIVE}, `AB`, []Match{[]Group{{0, 1}, {0, 1}}, []Group{{1, 2}, {1, 2}}, []Group{{2, 2}}}}, {`(a|b|c|d|e)f`, []ReFlag{RE_CASE_INSENSITIVE}, `EF`, []Match{[]Group{{0, 2}, {0, 1}}}}, {`(ab|cd)e`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCDE`, []Match{[]Group{{2, 5}, {2, 4}}}}, {`^(ab|cd)e`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCDE`, []Match{}}, {`(abc|)ef`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCDEF`, []Match{[]Group{{4, 6}, {4, 4}}}}, {`(a|b)c*d`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCD`, []Match{[]Group{{1, 4}, {1, 2}}}}, {`(ab|ab*)bc`, []ReFlag{RE_CASE_INSENSITIVE}, `ABC`, []Match{[]Group{{0, 3}, {0, 1}}}}, {`a([bc]*)c*`, []ReFlag{RE_CASE_INSENSITIVE}, `ABC`, []Match{[]Group{{0, 3}, {1, 3}}}}, {`a([bc]*)(c*d)`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCD`, []Match{[]Group{{0, 4}, {1, 3}, {3, 4}}}}, {`a([bc]+)(c*d)`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCD`, []Match{[]Group{{0, 4}, {1, 3}, {3, 4}}}}, {`a([bc]*)(c+d)`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCD`, []Match{[]Group{{0, 4}, {1, 2}, {2, 4}}}}, {`(ab|a)b*c`, []ReFlag{RE_CASE_INSENSITIVE}, `ABC`, []Match{[]Group{{0, 3}, {0, 2}}}}, {`((a)(b)c)(d)`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCD`, []Match{[]Group{{0, 4}, {0, 3}, {0, 1}, {1, 2}, {3, 4}}}}, {`^a(bc+|b[eh])g|.h$`, []ReFlag{RE_CASE_INSENSITIVE}, `ABH`, []Match{[]Group{{1, 3}}}}, {`(bc+d$|ef*g.|h?i(j|k))`, []ReFlag{RE_CASE_INSENSITIVE}, `EFFGZ`, []Match{[]Group{{0, 5}, {0, 5}}}}, {`(bc+d$|ef*g.|h?i(j|k))`, []ReFlag{RE_CASE_INSENSITIVE}, `IJ`, []Match{[]Group{{0, 2}, {0, 2}, {1, 2}}}}, {`(bc+d$|ef*g.|h?i(j|k))`, []ReFlag{RE_CASE_INSENSITIVE}, `EFFG`, []Match{}}, {`(bc+d$|ef*g.|h?i(j|k))`, []ReFlag{RE_CASE_INSENSITIVE}, `BCDD`, []Match{}}, {`(bc+d$|ef*g.|h?i(j|k))`, []ReFlag{RE_CASE_INSENSITIVE}, `reffgz`, []Match{[]Group{{1, 6}, {1, 6}}}}, {`(((((((((a)))))))))`, []ReFlag{RE_CASE_INSENSITIVE}, `A`, []Match{[]Group{{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}}}}, {`(((((((((a)))))))))\41`, []ReFlag{RE_CASE_INSENSITIVE}, `A`, []Match{[]Group{{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}}}}, {`(.*)c(.*)`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCDE`, []Match{[]Group{{0, 5}, {0, 2}, {3, 5}}}}, {`\((.*), (.*)\)`, []ReFlag{RE_CASE_INSENSITIVE}, `(A, B)`, []Match{[]Group{{0, 6}, {1, 2}, {4, 5}}}}, {`(a)(b)c|ab`, []ReFlag{RE_CASE_INSENSITIVE}, `AB`, []Match{[]Group{{0, 2}}}}, {`(a)+x`, []ReFlag{RE_CASE_INSENSITIVE}, `AAAX`, []Match{[]Group{{0, 4}, {2, 3}}}}, {`([ac])+x`, []ReFlag{RE_CASE_INSENSITIVE}, `AACX`, []Match{[]Group{{0, 4}, {2, 3}}}}, {`([^/]*/)*sub1/`, []ReFlag{RE_CASE_INSENSITIVE}, `D:MSGS/TDIR/SUB1/TRIAL/AWAY.CPP`, []Match{[]Group{{0, 17}, {7, 12}}}}, {`([^.]*)\.([^:]*):[T ]+(.*)`, []ReFlag{RE_CASE_INSENSITIVE}, `TRACK1.TITLE:TBLAH BLAH BLAH`, []Match{[]Group{{0, 28}, {0, 6}, {7, 12}, {14, 28}}}}, {`([^N]*N)+`, []ReFlag{RE_CASE_INSENSITIVE}, `ABNNXYZN`, []Match{[]Group{{0, 8}, {4, 8}}}}, {`([^N]*N)+`, []ReFlag{RE_CASE_INSENSITIVE}, `ABNNXYZ`, []Match{[]Group{{0, 4}, {3, 4}}}}, {`([abc]*)x`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCX`, []Match{[]Group{{0, 4}, {0, 3}}}}, {`([abc]*)x`, []ReFlag{RE_CASE_INSENSITIVE}, `ABC`, []Match{}}, {`([xyz]*)x`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCX`, []Match{[]Group{{3, 4}, {3, 3}}}}, {`(a)+b|aac`, []ReFlag{RE_CASE_INSENSITIVE}, `AAC`, []Match{[]Group{{0, 3}}}}, {`([abc])*d`, []ReFlag{RE_CASE_INSENSITIVE}, `ABBBCD`, []Match{[]Group{{0, 6}, {4, 5}}}}, {`([abc])*bcd`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCD`, []Match{[]Group{{0, 4}, {0, 1}}}}, {`^(ab|cd)e`, []ReFlag{RE_CASE_INSENSITIVE}, `ABCDE`, []Match{}}, {`(?:(?:(?:(?:(?:(?:a))))))`, nil, `a`, []Match{[]Group{{0, 1}}}}, {`a(?:b|c|d)(.)`, nil, `ace`, []Match{[]Group{{0, 3}, {2, 3}}}}, {`a(?:b|c|d)*(.)`, nil, `ace`, []Match{[]Group{{0, 3}, {2, 3}}}}, {`a(?:b|c|d)+(.)`, nil, `ace`, []Match{[]Group{{0, 3}, {2, 3}}}}, {`a(?:b|(c|e){1,2}?|d)+(.)`, nil, `ace`, []Match{[]Group{{0, 3}, {1, 2}, {2, 3}}}}, {`(?)`, nil, `391`, []Match{[]Group{{0, 3}, {0, 3}}}}, } func TestFind(t *testing.T) { for _, test := range reTests { t.Run(test.re+" "+test.str, func(t *testing.T) { regComp, err := Compile(test.re, test.flags...) if err != nil { if test.result != nil { panic(fmt.Errorf("Test Error: %v", err)) } } else { groupIndex, err := regComp.Find(test.str) if err != nil { // No matches found if len(test.result) == 0 { return // Manually pass the test, because this is the expected behavior } else { t.Errorf("Wanted no match Got %v\n", groupIndex) } } else { if groupIndex != test.result[0] { t.Errorf("Wanted %v Got %v\n", test.result, groupIndex) } } } }) } } func TestFindAll(t *testing.T) { for _, test := range reTests { t.Run(test.re+" "+test.str, func(t *testing.T) { regComp, err := Compile(test.re, test.flags...) if err != nil { if test.result != nil { panic(fmt.Errorf("Test Error: %v", err)) } } else { matchIndices := regComp.FindAll(test.str) if !slices.Equal(test.result, matchIndices) { t.Errorf("Wanted %v Got %v\n", test.result, matchIndices) } } }) } } func TestFindString(t *testing.T) { for _, test := range reTests { t.Run(test.re+" "+test.str, func(t *testing.T) { regComp, err := Compile(test.re, test.flags...) if err != nil { if test.result != nil { panic(err) } } else { foundString := regComp.FindString(test.str) if len(test.result) == 0 { if foundString != "" { t.Errorf("Expected no match got %v\n", foundString) } } else { expectedString := test.str[test.result[0].StartIdx:test.result[0].EndIdx] if foundString != expectedString { t.Errorf("Wanted %v Got %v\n", expectedString, foundString) } } } }) } } func TestFindAllString(t *testing.T) { for _, test := range reTests { t.Run(test.re+" "+test.str, func(t *testing.T) { regComp, err := Compile(test.re, test.flags...) if err != nil { if test.result != nil { panic(err) } } else { foundStrings := regComp.FindAllString(test.str) if len(test.result) != len(foundStrings) { t.Errorf("Differing number of matches: Wanted %v matches Got %v matches\n", len(test.result), len(foundStrings)) } else { for idx, group := range test.result { groupStr := test.str[group.StartIdx:group.EndIdx] if groupStr != foundStrings[idx] { t.Errorf("Wanted %v Got %v\n", groupStr, foundStrings[idx]) } } } } }) } } func TestFindSubmatch(t *testing.T) { for _, test := range groupTests { t.Run(test.re+" "+test.str, func(t *testing.T) { regComp, err := Compile(test.re, test.flags...) if err != nil { if test.result != nil { panic(err) } } match, err := regComp.FindSubmatch(test.str) for i := range match { if match[i].IsValid() { if test.result[0][i] != match[i] { t.Errorf("Wanted %v Got %v\n", test.result[0], match) } } } }) } } func TestFindAllSubmatch(t *testing.T) { for _, test := range groupTests { t.Run(test.re+" "+test.str, func(t *testing.T) { regComp, err := Compile(test.re, test.flags...) if err != nil { if test.result != nil { panic(err) } } matchIndices := regComp.FindAllSubmatch(test.str) for i := range matchIndices { for j := range matchIndices[i] { if matchIndices[i][j].IsValid() { if test.result[i][j] != matchIndices[i][j] { t.Errorf("Wanted %v Got %v\n", test.result, matchIndices) } } } } }) } }