diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-01-17 12:40:45 +0100 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-01-17 12:40:45 +0100 |
commit | 3e45412327a2654a77944249962b3652e6142299 (patch) | |
tree | bc3bf69452afa055423cbe0c5cfa8ca357df6ccf /src/pkg/regexp/all_test.go | |
parent | c533680039762cacbc37db8dc7eed074c3e497be (diff) | |
download | golang-3e45412327a2654a77944249962b3652e6142299.tar.gz |
Imported Upstream version 2011.01.12upstream/2011.01.12
Diffstat (limited to 'src/pkg/regexp/all_test.go')
-rw-r--r-- | src/pkg/regexp/all_test.go | 479 |
1 files changed, 155 insertions, 324 deletions
diff --git a/src/pkg/regexp/all_test.go b/src/pkg/regexp/all_test.go index 4bdd6c67e..3b2c489bc 100644 --- a/src/pkg/regexp/all_test.go +++ b/src/pkg/regexp/all_test.go @@ -37,80 +37,18 @@ type stringError struct { } var bad_re = []stringError{ - stringError{`*`, ErrBareClosure}, - stringError{`(abc`, ErrUnmatchedLpar}, - stringError{`abc)`, ErrUnmatchedRpar}, - stringError{`x[a-z`, ErrUnmatchedLbkt}, - stringError{`abc]`, ErrUnmatchedRbkt}, - stringError{`[z-a]`, ErrBadRange}, - stringError{`abc\`, ErrExtraneousBackslash}, - stringError{`a**`, ErrBadClosure}, - stringError{`a*+`, ErrBadClosure}, - stringError{`a??`, ErrBadClosure}, - stringError{`*`, ErrBareClosure}, - stringError{`\x`, ErrBadBackslash}, -} - -type vec []int - -type tester struct { - re string - text string - match vec -} - -var matches = []tester{ - tester{`^abcdefg`, "abcdefg", vec{0, 7}}, - tester{`a+`, "baaab", vec{1, 4}}, - tester{"abcd..", "abcdef", vec{0, 6}}, - tester{``, "", vec{0, 0}}, - tester{`a`, "a", vec{0, 1}}, - tester{`x`, "y", vec{}}, - tester{`b`, "abc", vec{1, 2}}, - tester{`.`, "a", vec{0, 1}}, - tester{`.*`, "abcdef", vec{0, 6}}, - tester{`^`, "abcde", vec{0, 0}}, - tester{`$`, "abcde", vec{5, 5}}, - tester{`^abcd$`, "abcd", vec{0, 4}}, - tester{`^bcd'`, "abcdef", vec{}}, - tester{`^abcd$`, "abcde", vec{}}, - tester{`a+`, "baaab", vec{1, 4}}, - tester{`a*`, "baaab", vec{0, 0}}, - tester{`[a-z]+`, "abcd", vec{0, 4}}, - tester{`[^a-z]+`, "ab1234cd", vec{2, 6}}, - tester{`[a\-\]z]+`, "az]-bcz", vec{0, 4}}, - tester{`[^\n]+`, "abcd\n", vec{0, 4}}, - tester{`[日本語]+`, "日本語日本語", vec{0, 18}}, - tester{`日本語+`, "日本語", vec{0, 9}}, - tester{`日本語+`, "日本語語語語", vec{0, 18}}, - tester{`()`, "", vec{0, 0, 0, 0}}, - tester{`(a)`, "a", vec{0, 1, 0, 1}}, - tester{`(.)(.)`, "日a", vec{0, 4, 0, 3, 3, 4}}, - tester{`(.*)`, "", vec{0, 0, 0, 0}}, - tester{`(.*)`, "abcd", vec{0, 4, 0, 4}}, - tester{`(..)(..)`, "abcd", vec{0, 4, 0, 2, 2, 4}}, - tester{`(([^xyz]*)(d))`, "abcd", vec{0, 4, 0, 4, 0, 3, 3, 4}}, - tester{`((a|b|c)*(d))`, "abcd", vec{0, 4, 0, 4, 2, 3, 3, 4}}, - tester{`(((a|b|c)*)(d))`, "abcd", vec{0, 4, 0, 4, 0, 3, 2, 3, 3, 4}}, - tester{`a*(|(b))c*`, "aacc", vec{0, 4, 2, 2, -1, -1}}, - tester{`(.*).*`, "ab", vec{0, 2, 0, 2}}, - tester{`[.]`, ".", vec{0, 1}}, - tester{`/$`, "/abc/", vec{4, 5}}, - tester{`/$`, "/abc", vec{}}, - - // fixed bugs - tester{`ab$`, "cab", vec{1, 3}}, - tester{`axxb$`, "axxcb", vec{}}, - tester{`data`, "daXY data", vec{5, 9}}, - tester{`da(.)a$`, "daXY data", vec{5, 9, 7, 8}}, - - // can backslash-escape any punctuation - tester{`\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\{\|\}\~`, - `!"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, vec{0, 31}}, - tester{`[\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\{\|\}\~]+`, - `!"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, vec{0, 31}}, - tester{"\\`", "`", vec{0, 1}}, - tester{"[\\`]+", "`", vec{0, 1}}, + {`*`, ErrBareClosure}, + {`(abc`, ErrUnmatchedLpar}, + {`abc)`, ErrUnmatchedRpar}, + {`x[a-z`, ErrUnmatchedLbkt}, + {`abc]`, ErrUnmatchedRbkt}, + {`[z-a]`, ErrBadRange}, + {`abc\`, ErrExtraneousBackslash}, + {`a**`, ErrBadClosure}, + {`a*+`, ErrBadClosure}, + {`a??`, ErrBadClosure}, + {`*`, ErrBareClosure}, + {`\x`, ErrBadBackslash}, } func compileTest(t *testing.T, expr string, error os.Error) *Regexp { @@ -121,66 +59,6 @@ func compileTest(t *testing.T, expr string, error os.Error) *Regexp { return re } -func printVec(t *testing.T, m []int) { - l := len(m) - if l == 0 { - t.Log("\t<no match>") - } else { - if m[len(m)-1] == -1 { - m = m[0 : len(m)-2] - } - t.Log("\t", m) - } -} - -func equal(m1, m2 []int) bool { - l := len(m1) - if l != len(m2) { - return false - } - for i := 0; i < l; i++ { - if m1[i] != m2[i] { - return false - } - } - return true -} - -func equalStrings(m1, m2 []string) bool { - l := len(m1) - if l != len(m2) { - return false - } - for i := 0; i < l; i++ { - if m1[i] != m2[i] { - return false - } - } - return true -} - -func executeTest(t *testing.T, expr string, str string, match []int) { - re := compileTest(t, expr, nil) - if re == nil { - return - } - m := re.ExecuteString(str) - if !equal(m, match) { - t.Errorf("ExecuteString failure on %#q matching %q:", expr, str) - printVec(t, m) - t.Log("should be:") - printVec(t, match) - } - // now try bytes - m = re.Execute([]byte(str)) - if !equal(m, match) { - t.Errorf("Execute failure on %#q matching %q:", expr, str) - printVec(t, m) - t.Log("should be:") - printVec(t, match) - } -} - func TestGoodCompile(t *testing.T) { for i := 0; i < len(good_re); i++ { compileTest(t, good_re[i], nil) @@ -193,57 +71,41 @@ func TestBadCompile(t *testing.T) { } } -func TestExecute(t *testing.T) { - for i := 0; i < len(matches); i++ { - test := &matches[i] - executeTest(t, test.re, test.text, test.match) - } -} - -func matchTest(t *testing.T, expr string, str string, match []int) { - re := compileTest(t, expr, nil) +func matchTest(t *testing.T, test *FindTest) { + re := compileTest(t, test.pat, nil) if re == nil { return } - m := re.MatchString(str) - if m != (len(match) > 0) { - t.Errorf("MatchString failure on %#q matching %q: %t should be %t", expr, str, m, len(match) > 0) + m := re.MatchString(test.text) + if m != (len(test.matches) > 0) { + t.Errorf("MatchString failure on %s: %t should be %t", test, m, len(test.matches) > 0) } // now try bytes - m = re.Match([]byte(str)) - if m != (len(match) > 0) { - t.Errorf("Match failure on %#q matching %q: %t should be %t", expr, str, m, len(match) > 0) + m = re.Match([]byte(test.text)) + if m != (len(test.matches) > 0) { + t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0) } } func TestMatch(t *testing.T) { - for i := 0; i < len(matches); i++ { - test := &matches[i] - matchTest(t, test.re, test.text, test.match) + for _, test := range findTests { + matchTest(t, &test) } } -func TestMatchStrings(t *testing.T) { - for i := 0; i < len(matches); i++ { - test := &matches[i] - matchTest(t, test.re, test.text, test.match) - } -} - -func matchFunctionTest(t *testing.T, expr string, str string, match []int) { - m, err := MatchString(expr, str) +func matchFunctionTest(t *testing.T, test *FindTest) { + m, err := MatchString(test.pat, test.text) if err == nil { return } - if m != (len(match) > 0) { - t.Errorf("Match failure on %#q matching %q: %d should be %d", expr, str, m, len(match) > 0) + if m != (len(test.matches) > 0) { + t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0) } } func TestMatchFunction(t *testing.T) { - for i := 0; i < len(matches); i++ { - test := &matches[i] - matchFunctionTest(t, test.re, test.text, test.match) + for _, test := range findTests { + matchFunctionTest(t, &test) } } @@ -253,64 +115,64 @@ type ReplaceTest struct { var replaceTests = []ReplaceTest{ // Test empty input and/or replacement, with pattern that matches the empty string. - ReplaceTest{"", "", "", ""}, - ReplaceTest{"", "x", "", "x"}, - ReplaceTest{"", "", "abc", "abc"}, - ReplaceTest{"", "x", "abc", "xaxbxcx"}, + {"", "", "", ""}, + {"", "x", "", "x"}, + {"", "", "abc", "abc"}, + {"", "x", "abc", "xaxbxcx"}, // Test empty input and/or replacement, with pattern that does not match the empty string. - ReplaceTest{"b", "", "", ""}, - ReplaceTest{"b", "x", "", ""}, - ReplaceTest{"b", "", "abc", "ac"}, - ReplaceTest{"b", "x", "abc", "axc"}, - ReplaceTest{"y", "", "", ""}, - ReplaceTest{"y", "x", "", ""}, - ReplaceTest{"y", "", "abc", "abc"}, - ReplaceTest{"y", "x", "abc", "abc"}, + {"b", "", "", ""}, + {"b", "x", "", ""}, + {"b", "", "abc", "ac"}, + {"b", "x", "abc", "axc"}, + {"y", "", "", ""}, + {"y", "x", "", ""}, + {"y", "", "abc", "abc"}, + {"y", "x", "abc", "abc"}, // Multibyte characters -- verify that we don't try to match in the middle // of a character. - ReplaceTest{"[a-c]*", "x", "\u65e5", "x\u65e5x"}, - ReplaceTest{"[^\u65e5]", "x", "abc\u65e5def", "xxx\u65e5xxx"}, + {"[a-c]*", "x", "\u65e5", "x\u65e5x"}, + {"[^\u65e5]", "x", "abc\u65e5def", "xxx\u65e5xxx"}, // Start and end of a string. - ReplaceTest{"^[a-c]*", "x", "abcdabc", "xdabc"}, - ReplaceTest{"[a-c]*$", "x", "abcdabc", "abcdx"}, - ReplaceTest{"^[a-c]*$", "x", "abcdabc", "abcdabc"}, - ReplaceTest{"^[a-c]*", "x", "abc", "x"}, - ReplaceTest{"[a-c]*$", "x", "abc", "x"}, - ReplaceTest{"^[a-c]*$", "x", "abc", "x"}, - ReplaceTest{"^[a-c]*", "x", "dabce", "xdabce"}, - ReplaceTest{"[a-c]*$", "x", "dabce", "dabcex"}, - ReplaceTest{"^[a-c]*$", "x", "dabce", "dabce"}, - ReplaceTest{"^[a-c]*", "x", "", "x"}, - ReplaceTest{"[a-c]*$", "x", "", "x"}, - ReplaceTest{"^[a-c]*$", "x", "", "x"}, - - ReplaceTest{"^[a-c]+", "x", "abcdabc", "xdabc"}, - ReplaceTest{"[a-c]+$", "x", "abcdabc", "abcdx"}, - ReplaceTest{"^[a-c]+$", "x", "abcdabc", "abcdabc"}, - ReplaceTest{"^[a-c]+", "x", "abc", "x"}, - ReplaceTest{"[a-c]+$", "x", "abc", "x"}, - ReplaceTest{"^[a-c]+$", "x", "abc", "x"}, - ReplaceTest{"^[a-c]+", "x", "dabce", "dabce"}, - ReplaceTest{"[a-c]+$", "x", "dabce", "dabce"}, - ReplaceTest{"^[a-c]+$", "x", "dabce", "dabce"}, - ReplaceTest{"^[a-c]+", "x", "", ""}, - ReplaceTest{"[a-c]+$", "x", "", ""}, - ReplaceTest{"^[a-c]+$", "x", "", ""}, + {"^[a-c]*", "x", "abcdabc", "xdabc"}, + {"[a-c]*$", "x", "abcdabc", "abcdx"}, + {"^[a-c]*$", "x", "abcdabc", "abcdabc"}, + {"^[a-c]*", "x", "abc", "x"}, + {"[a-c]*$", "x", "abc", "x"}, + {"^[a-c]*$", "x", "abc", "x"}, + {"^[a-c]*", "x", "dabce", "xdabce"}, + {"[a-c]*$", "x", "dabce", "dabcex"}, + {"^[a-c]*$", "x", "dabce", "dabce"}, + {"^[a-c]*", "x", "", "x"}, + {"[a-c]*$", "x", "", "x"}, + {"^[a-c]*$", "x", "", "x"}, + + {"^[a-c]+", "x", "abcdabc", "xdabc"}, + {"[a-c]+$", "x", "abcdabc", "abcdx"}, + {"^[a-c]+$", "x", "abcdabc", "abcdabc"}, + {"^[a-c]+", "x", "abc", "x"}, + {"[a-c]+$", "x", "abc", "x"}, + {"^[a-c]+$", "x", "abc", "x"}, + {"^[a-c]+", "x", "dabce", "dabce"}, + {"[a-c]+$", "x", "dabce", "dabce"}, + {"^[a-c]+$", "x", "dabce", "dabce"}, + {"^[a-c]+", "x", "", ""}, + {"[a-c]+$", "x", "", ""}, + {"^[a-c]+$", "x", "", ""}, // Other cases. - ReplaceTest{"abc", "def", "abcdefg", "defdefg"}, - ReplaceTest{"bc", "BC", "abcbcdcdedef", "aBCBCdcdedef"}, - ReplaceTest{"abc", "", "abcdabc", "d"}, - ReplaceTest{"x", "xXx", "xxxXxxx", "xXxxXxxXxXxXxxXxxXx"}, - ReplaceTest{"abc", "d", "", ""}, - ReplaceTest{"abc", "d", "abc", "d"}, - ReplaceTest{".+", "x", "abc", "x"}, - ReplaceTest{"[a-c]*", "x", "def", "xdxexfx"}, - ReplaceTest{"[a-c]+", "x", "abcbcdcdedef", "xdxdedef"}, - ReplaceTest{"[a-c]*", "x", "abcbcdcdedef", "xdxdxexdxexfx"}, + {"abc", "def", "abcdefg", "defdefg"}, + {"bc", "BC", "abcbcdcdedef", "aBCBCdcdedef"}, + {"abc", "", "abcdabc", "d"}, + {"x", "xXx", "xxxXxxx", "xXxxXxxXxXxXxxXxxXx"}, + {"abc", "d", "", ""}, + {"abc", "d", "abc", "d"}, + {".+", "x", "abc", "x"}, + {"[a-c]*", "x", "def", "xdxexfx"}, + {"[a-c]+", "x", "abcbcdcdedef", "xdxdedef"}, + {"[a-c]*", "x", "abcbcdcdedef", "xdxdxexdxexfx"}, } type ReplaceFuncTest struct { @@ -320,9 +182,9 @@ type ReplaceFuncTest struct { } var replaceFuncTests = []ReplaceFuncTest{ - ReplaceFuncTest{"[a-c]", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxayxbyxcydef"}, - ReplaceFuncTest{"[a-c]+", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxabcydef"}, - ReplaceFuncTest{"[a-c]*", func(s string) string { return "x" + s + "y" }, "defabcdef", "xydxyexyfxabcydxyexyfxy"}, + {"[a-c]", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxayxbyxcydef"}, + {"[a-c]+", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxabcydef"}, + {"[a-c]*", func(s string) string { return "x" + s + "y" }, "defabcdef", "xydxyexyfxabcydxyexyfxy"}, } func TestReplaceAll(t *testing.T) { @@ -367,18 +229,21 @@ func TestReplaceAllFunc(t *testing.T) { } } -type QuoteMetaTest struct { - pattern, output string +type MetaTest struct { + pattern, output, literal string + isLiteral bool } -var quoteMetaTests = []QuoteMetaTest{ - QuoteMetaTest{``, ``}, - QuoteMetaTest{`foo`, `foo`}, - QuoteMetaTest{`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[{\]}\\\|,<\.>/\?~`}, +var metaTests = []MetaTest{ + {``, ``, ``, true}, + {`foo`, `foo`, `foo`, true}, + {`foo\.\$`, `foo\\\.\\\$`, `foo.$`, true}, // has meta but no operator + {`foo.\$`, `foo\.\\\$`, `foo`, false}, // has escaped operators and real operators + {`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[{\]}\\\|,<\.>/\?~`, `!@#`, false}, } func TestQuoteMeta(t *testing.T) { - for _, tc := range quoteMetaTests { + for _, tc := range metaTests { // Verify that QuoteMeta returns the expected string. quoted := QuoteMeta(tc.pattern) if quoted != tc.output { @@ -407,96 +272,16 @@ func TestQuoteMeta(t *testing.T) { } } -type matchCase struct { - matchfunc string - input string - n int - regexp string - expected []string -} - -var matchCases = []matchCase{ - matchCase{"match", " aa b", 0, "[^ ]+", []string{"aa", "b"}}, - matchCase{"match", " aa b", 0, "[^ ]*", []string{"", "aa", "b"}}, - matchCase{"match", "a b c", 0, "[^ ]*", []string{"a", "b", "c"}}, - matchCase{"match", "a:a: a:", 0, "^.:", []string{"a:"}}, - matchCase{"match", "", 0, "[^ ]*", []string{""}}, - matchCase{"match", "", 0, "", []string{""}}, - matchCase{"match", "a", 0, "", []string{"", ""}}, - matchCase{"match", "ab", 0, "^", []string{""}}, - matchCase{"match", "ab", 0, "$", []string{""}}, - matchCase{"match", "ab", 0, "X*", []string{"", "", ""}}, - matchCase{"match", "aX", 0, "X*", []string{"", "X"}}, - matchCase{"match", "XabX", 0, "X*", []string{"X", "", "X"}}, - - matchCase{"matchit", "", 0, ".", []string{}}, - matchCase{"matchit", "abc", 2, ".", []string{"a", "b"}}, - matchCase{"matchit", "abc", 0, ".", []string{"a", "b", "c"}}, -} - -func printStringSlice(t *testing.T, s []string) { - t.Logf("%#v", s) -} - -func TestAllMatches(t *testing.T) { - ch := make(chan matchCase) - go func() { - for _, c := range matchCases { - ch <- c - stringCase := matchCase{ - "string" + c.matchfunc, - c.input, - c.n, - c.regexp, - c.expected, - } - ch <- stringCase - } - close(ch) - }() - - for c := range ch { - var result []string - re, _ := Compile(c.regexp) - - switch c.matchfunc { - case "matchit": - result = make([]string, len(c.input)+1) - i := 0 - b := []byte(c.input) - for match := range re.AllMatchesIter(b, c.n) { - result[i] = string(match) - i++ - } - result = result[0:i] - case "stringmatchit": - result = make([]string, len(c.input)+1) - i := 0 - for match := range re.AllMatchesStringIter(c.input, c.n) { - result[i] = match - i++ - } - result = result[0:i] - case "match": - result = make([]string, len(c.input)+1) - b := []byte(c.input) - i := 0 - for _, match := range re.AllMatches(b, c.n) { - result[i] = string(match) - i++ - } - result = result[0:i] - case "stringmatch": - result = re.AllMatchesString(c.input, c.n) +func TestLiteralPrefix(t *testing.T) { + for _, tc := range metaTests { + // Literal method needs to scan the pattern. + re := MustCompile(tc.pattern) + str, complete := re.LiteralPrefix() + if complete != tc.isLiteral { + t.Errorf("LiteralPrefix(`%s`) = %t; want %t", tc.pattern, complete, tc.isLiteral) } - - if !equalStrings(result, c.expected) { - t.Errorf("testing '%s'.%s('%s', %d), expected: ", - c.regexp, c.matchfunc, c.input, c.n) - printStringSlice(t, c.expected) - t.Log("got: ") - printStringSlice(t, result) - t.Log("\n") + if str != tc.literal { + t.Errorf("LiteralPrefix(`%s`) = `%s`; want `%s`", tc.pattern, str, tc.literal) } } } @@ -507,16 +292,16 @@ type numSubexpCase struct { } var numSubexpCases = []numSubexpCase{ - numSubexpCase{``, 0}, - numSubexpCase{`.*`, 0}, - numSubexpCase{`abba`, 0}, - numSubexpCase{`ab(b)a`, 1}, - numSubexpCase{`ab(.*)a`, 1}, - numSubexpCase{`(.*)ab(.*)a`, 2}, - numSubexpCase{`(.*)(ab)(.*)a`, 3}, - numSubexpCase{`(.*)((a)b)(.*)a`, 4}, - numSubexpCase{`(.*)(\(ab)(.*)a`, 3}, - numSubexpCase{`(.*)(\(a\)b)(.*)a`, 3}, + {``, 0}, + {`.*`, 0}, + {`abba`, 0}, + {`ab(b)a`, 1}, + {`ab(.*)a`, 1}, + {`(.*)ab(.*)a`, 2}, + {`(.*)(ab)(.*)a`, 3}, + {`(.*)((a)b)(.*)a`, 4}, + {`(.*)(\(ab)(.*)a`, 3}, + {`(.*)(\(a\)b)(.*)a`, 3}, } func TestNumSubexp(t *testing.T) { @@ -592,3 +377,49 @@ func BenchmarkReplaceAll(b *testing.B) { re.ReplaceAllString(x, "") } } + +func BenchmarkAnchoredLiteralShortNonMatch(b *testing.B) { + b.StopTimer() + x := []byte("abcdefghijklmnopqrstuvwxyz") + re := MustCompile("^zbc(d|e)") + b.StartTimer() + for i := 0; i < b.N; i++ { + re.Match(x) + } +} + +func BenchmarkAnchoredLiteralLongNonMatch(b *testing.B) { + b.StopTimer() + x := []byte("abcdefghijklmnopqrstuvwxyz") + for i := 0; i < 15; i++ { + x = append(x, x...) + } + re := MustCompile("^zbc(d|e)") + b.StartTimer() + for i := 0; i < b.N; i++ { + re.Match(x) + } +} + +func BenchmarkAnchoredShortMatch(b *testing.B) { + b.StopTimer() + x := []byte("abcdefghijklmnopqrstuvwxyz") + re := MustCompile("^.bc(d|e)") + b.StartTimer() + for i := 0; i < b.N; i++ { + re.Match(x) + } +} + +func BenchmarkAnchoredLongMatch(b *testing.B) { + b.StopTimer() + x := []byte("abcdefghijklmnopqrstuvwxyz") + for i := 0; i < 15; i++ { + x = append(x, x...) + } + re := MustCompile("^.bc(d|e)") + b.StartTimer() + for i := 0; i < b.N; i++ { + re.Match(x) + } +} |