Run Format

Source file src/pkg/regexp/all_test.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package regexp
     6	
     7	import (
     8		"reflect"
     9		"strings"
    10		"testing"
    11	)
    12	
    13	var good_re = []string{
    14		``,
    15		`.`,
    16		`^.$`,
    17		`a`,
    18		`a*`,
    19		`a+`,
    20		`a?`,
    21		`a|b`,
    22		`a*|b*`,
    23		`(a*|b)(c*|d)`,
    24		`[a-z]`,
    25		`[a-abc-c\-\]\[]`,
    26		`[a-z]+`,
    27		`[abc]`,
    28		`[^1234]`,
    29		`[^\n]`,
    30		`\!\\`,
    31	}
    32	
    33	type stringError struct {
    34		re  string
    35		err string
    36	}
    37	
    38	var bad_re = []stringError{
    39		{`*`, "missing argument to repetition operator: `*`"},
    40		{`+`, "missing argument to repetition operator: `+`"},
    41		{`?`, "missing argument to repetition operator: `?`"},
    42		{`(abc`, "missing closing ): `(abc`"},
    43		{`abc)`, "unexpected ): `abc)`"},
    44		{`x[a-z`, "missing closing ]: `[a-z`"},
    45		{`[z-a]`, "invalid character class range: `z-a`"},
    46		{`abc\`, "trailing backslash at end of expression"},
    47		{`a**`, "invalid nested repetition operator: `**`"},
    48		{`a*+`, "invalid nested repetition operator: `*+`"},
    49		{`\x`, "invalid escape sequence: `\\x`"},
    50	}
    51	
    52	func compileTest(t *testing.T, expr string, error string) *Regexp {
    53		re, err := Compile(expr)
    54		if error == "" && err != nil {
    55			t.Error("compiling `", expr, "`; unexpected error: ", err.Error())
    56		}
    57		if error != "" && err == nil {
    58			t.Error("compiling `", expr, "`; missing error")
    59		} else if error != "" && !strings.Contains(err.Error(), error) {
    60			t.Error("compiling `", expr, "`; wrong error: ", err.Error(), "; want ", error)
    61		}
    62		return re
    63	}
    64	
    65	func TestGoodCompile(t *testing.T) {
    66		for i := 0; i < len(good_re); i++ {
    67			compileTest(t, good_re[i], "")
    68		}
    69	}
    70	
    71	func TestBadCompile(t *testing.T) {
    72		for i := 0; i < len(bad_re); i++ {
    73			compileTest(t, bad_re[i].re, bad_re[i].err)
    74		}
    75	}
    76	
    77	func matchTest(t *testing.T, test *FindTest) {
    78		re := compileTest(t, test.pat, "")
    79		if re == nil {
    80			return
    81		}
    82		m := re.MatchString(test.text)
    83		if m != (len(test.matches) > 0) {
    84			t.Errorf("MatchString failure on %s: %t should be %t", test, m, len(test.matches) > 0)
    85		}
    86		// now try bytes
    87		m = re.Match([]byte(test.text))
    88		if m != (len(test.matches) > 0) {
    89			t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0)
    90		}
    91	}
    92	
    93	func TestMatch(t *testing.T) {
    94		for _, test := range findTests {
    95			matchTest(t, &test)
    96		}
    97	}
    98	
    99	func matchFunctionTest(t *testing.T, test *FindTest) {
   100		m, err := MatchString(test.pat, test.text)
   101		if err == nil {
   102			return
   103		}
   104		if m != (len(test.matches) > 0) {
   105			t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0)
   106		}
   107	}
   108	
   109	func TestMatchFunction(t *testing.T) {
   110		for _, test := range findTests {
   111			matchFunctionTest(t, &test)
   112		}
   113	}
   114	
   115	type ReplaceTest struct {
   116		pattern, replacement, input, output string
   117	}
   118	
   119	var replaceTests = []ReplaceTest{
   120		// Test empty input and/or replacement, with pattern that matches the empty string.
   121		{"", "", "", ""},
   122		{"", "x", "", "x"},
   123		{"", "", "abc", "abc"},
   124		{"", "x", "abc", "xaxbxcx"},
   125	
   126		// Test empty input and/or replacement, with pattern that does not match the empty string.
   127		{"b", "", "", ""},
   128		{"b", "x", "", ""},
   129		{"b", "", "abc", "ac"},
   130		{"b", "x", "abc", "axc"},
   131		{"y", "", "", ""},
   132		{"y", "x", "", ""},
   133		{"y", "", "abc", "abc"},
   134		{"y", "x", "abc", "abc"},
   135	
   136		// Multibyte characters -- verify that we don't try to match in the middle
   137		// of a character.
   138		{"[a-c]*", "x", "\u65e5", "x\u65e5x"},
   139		{"[^\u65e5]", "x", "abc\u65e5def", "xxx\u65e5xxx"},
   140	
   141		// Start and end of a string.
   142		{"^[a-c]*", "x", "abcdabc", "xdabc"},
   143		{"[a-c]*$", "x", "abcdabc", "abcdx"},
   144		{"^[a-c]*$", "x", "abcdabc", "abcdabc"},
   145		{"^[a-c]*", "x", "abc", "x"},
   146		{"[a-c]*$", "x", "abc", "x"},
   147		{"^[a-c]*$", "x", "abc", "x"},
   148		{"^[a-c]*", "x", "dabce", "xdabce"},
   149		{"[a-c]*$", "x", "dabce", "dabcex"},
   150		{"^[a-c]*$", "x", "dabce", "dabce"},
   151		{"^[a-c]*", "x", "", "x"},
   152		{"[a-c]*$", "x", "", "x"},
   153		{"^[a-c]*$", "x", "", "x"},
   154	
   155		{"^[a-c]+", "x", "abcdabc", "xdabc"},
   156		{"[a-c]+$", "x", "abcdabc", "abcdx"},
   157		{"^[a-c]+$", "x", "abcdabc", "abcdabc"},
   158		{"^[a-c]+", "x", "abc", "x"},
   159		{"[a-c]+$", "x", "abc", "x"},
   160		{"^[a-c]+$", "x", "abc", "x"},
   161		{"^[a-c]+", "x", "dabce", "dabce"},
   162		{"[a-c]+$", "x", "dabce", "dabce"},
   163		{"^[a-c]+$", "x", "dabce", "dabce"},
   164		{"^[a-c]+", "x", "", ""},
   165		{"[a-c]+$", "x", "", ""},
   166		{"^[a-c]+$", "x", "", ""},
   167	
   168		// Other cases.
   169		{"abc", "def", "abcdefg", "defdefg"},
   170		{"bc", "BC", "abcbcdcdedef", "aBCBCdcdedef"},
   171		{"abc", "", "abcdabc", "d"},
   172		{"x", "xXx", "xxxXxxx", "xXxxXxxXxXxXxxXxxXx"},
   173		{"abc", "d", "", ""},
   174		{"abc", "d", "abc", "d"},
   175		{".+", "x", "abc", "x"},
   176		{"[a-c]*", "x", "def", "xdxexfx"},
   177		{"[a-c]+", "x", "abcbcdcdedef", "xdxdedef"},
   178		{"[a-c]*", "x", "abcbcdcdedef", "xdxdxexdxexfx"},
   179	
   180		// Substitutions
   181		{"a+", "($0)", "banana", "b(a)n(a)n(a)"},
   182		{"a+", "(${0})", "banana", "b(a)n(a)n(a)"},
   183		{"a+", "(${0})$0", "banana", "b(a)an(a)an(a)a"},
   184		{"a+", "(${0})$0", "banana", "b(a)an(a)an(a)a"},
   185		{"hello, (.+)", "goodbye, ${1}", "hello, world", "goodbye, world"},
   186		{"hello, (.+)", "goodbye, $1x", "hello, world", "goodbye, "},
   187		{"hello, (.+)", "goodbye, ${1}x", "hello, world", "goodbye, worldx"},
   188		{"hello, (.+)", "<$0><$1><$2><$3>", "hello, world", "<hello, world><world><><>"},
   189		{"hello, (?P<noun>.+)", "goodbye, $noun!", "hello, world", "goodbye, world!"},
   190		{"hello, (?P<noun>.+)", "goodbye, ${noun}", "hello, world", "goodbye, world"},
   191		{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "hi", "hihihi"},
   192		{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "bye", "byebyebye"},
   193		{"(?P<x>hi)|(?P<x>bye)", "$xyz", "hi", ""},
   194		{"(?P<x>hi)|(?P<x>bye)", "${x}yz", "hi", "hiyz"},
   195		{"(?P<x>hi)|(?P<x>bye)", "hello $$x", "hi", "hello $x"},
   196		{"a+", "${oops", "aaa", "${oops"},
   197		{"a+", "$$", "aaa", "$"},
   198		{"a+", "$", "aaa", "$"},
   199	
   200		// Substitution when subexpression isn't found
   201		{"(x)?", "$1", "123", "123"},
   202		{"abc", "$1", "123", "123"},
   203	}
   204	
   205	var replaceLiteralTests = []ReplaceTest{
   206		// Substitutions
   207		{"a+", "($0)", "banana", "b($0)n($0)n($0)"},
   208		{"a+", "(${0})", "banana", "b(${0})n(${0})n(${0})"},
   209		{"a+", "(${0})$0", "banana", "b(${0})$0n(${0})$0n(${0})$0"},
   210		{"a+", "(${0})$0", "banana", "b(${0})$0n(${0})$0n(${0})$0"},
   211		{"hello, (.+)", "goodbye, ${1}", "hello, world", "goodbye, ${1}"},
   212		{"hello, (?P<noun>.+)", "goodbye, $noun!", "hello, world", "goodbye, $noun!"},
   213		{"hello, (?P<noun>.+)", "goodbye, ${noun}", "hello, world", "goodbye, ${noun}"},
   214		{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "hi", "$x$x$x"},
   215		{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "bye", "$x$x$x"},
   216		{"(?P<x>hi)|(?P<x>bye)", "$xyz", "hi", "$xyz"},
   217		{"(?P<x>hi)|(?P<x>bye)", "${x}yz", "hi", "${x}yz"},
   218		{"(?P<x>hi)|(?P<x>bye)", "hello $$x", "hi", "hello $$x"},
   219		{"a+", "${oops", "aaa", "${oops"},
   220		{"a+", "$$", "aaa", "$$"},
   221		{"a+", "$", "aaa", "$"},
   222	}
   223	
   224	type ReplaceFuncTest struct {
   225		pattern       string
   226		replacement   func(string) string
   227		input, output string
   228	}
   229	
   230	var replaceFuncTests = []ReplaceFuncTest{
   231		{"[a-c]", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxayxbyxcydef"},
   232		{"[a-c]+", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxabcydef"},
   233		{"[a-c]*", func(s string) string { return "x" + s + "y" }, "defabcdef", "xydxyexyfxabcydxyexyfxy"},
   234	}
   235	
   236	func TestReplaceAll(t *testing.T) {
   237		for _, tc := range replaceTests {
   238			re, err := Compile(tc.pattern)
   239			if err != nil {
   240				t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
   241				continue
   242			}
   243			actual := re.ReplaceAllString(tc.input, tc.replacement)
   244			if actual != tc.output {
   245				t.Errorf("%q.ReplaceAllString(%q,%q) = %q; want %q",
   246					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   247			}
   248			// now try bytes
   249			actual = string(re.ReplaceAll([]byte(tc.input), []byte(tc.replacement)))
   250			if actual != tc.output {
   251				t.Errorf("%q.ReplaceAll(%q,%q) = %q; want %q",
   252					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   253			}
   254		}
   255	}
   256	
   257	func TestReplaceAllLiteral(t *testing.T) {
   258		// Run ReplaceAll tests that do not have $ expansions.
   259		for _, tc := range replaceTests {
   260			if strings.Contains(tc.replacement, "$") {
   261				continue
   262			}
   263			re, err := Compile(tc.pattern)
   264			if err != nil {
   265				t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
   266				continue
   267			}
   268			actual := re.ReplaceAllLiteralString(tc.input, tc.replacement)
   269			if actual != tc.output {
   270				t.Errorf("%q.ReplaceAllLiteralString(%q,%q) = %q; want %q",
   271					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   272			}
   273			// now try bytes
   274			actual = string(re.ReplaceAllLiteral([]byte(tc.input), []byte(tc.replacement)))
   275			if actual != tc.output {
   276				t.Errorf("%q.ReplaceAllLiteral(%q,%q) = %q; want %q",
   277					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   278			}
   279		}
   280	
   281		// Run literal-specific tests.
   282		for _, tc := range replaceLiteralTests {
   283			re, err := Compile(tc.pattern)
   284			if err != nil {
   285				t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
   286				continue
   287			}
   288			actual := re.ReplaceAllLiteralString(tc.input, tc.replacement)
   289			if actual != tc.output {
   290				t.Errorf("%q.ReplaceAllLiteralString(%q,%q) = %q; want %q",
   291					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   292			}
   293			// now try bytes
   294			actual = string(re.ReplaceAllLiteral([]byte(tc.input), []byte(tc.replacement)))
   295			if actual != tc.output {
   296				t.Errorf("%q.ReplaceAllLiteral(%q,%q) = %q; want %q",
   297					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   298			}
   299		}
   300	}
   301	
   302	func TestReplaceAllFunc(t *testing.T) {
   303		for _, tc := range replaceFuncTests {
   304			re, err := Compile(tc.pattern)
   305			if err != nil {
   306				t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
   307				continue
   308			}
   309			actual := re.ReplaceAllStringFunc(tc.input, tc.replacement)
   310			if actual != tc.output {
   311				t.Errorf("%q.ReplaceFunc(%q,fn) = %q; want %q",
   312					tc.pattern, tc.input, actual, tc.output)
   313			}
   314			// now try bytes
   315			actual = string(re.ReplaceAllFunc([]byte(tc.input), func(s []byte) []byte { return []byte(tc.replacement(string(s))) }))
   316			if actual != tc.output {
   317				t.Errorf("%q.ReplaceFunc(%q,fn) = %q; want %q",
   318					tc.pattern, tc.input, actual, tc.output)
   319			}
   320		}
   321	}
   322	
   323	type MetaTest struct {
   324		pattern, output, literal string
   325		isLiteral                bool
   326	}
   327	
   328	var metaTests = []MetaTest{
   329		{``, ``, ``, true},
   330		{`foo`, `foo`, `foo`, true},
   331		{`foo\.\$`, `foo\\\.\\\$`, `foo.$`, true}, // has meta but no operator
   332		{`foo.\$`, `foo\.\\\$`, `foo`, false},     // has escaped operators and real operators
   333		{`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[\{\]\}\\\|,<\.>/\?~`, `!@#`, false},
   334	}
   335	
   336	func TestQuoteMeta(t *testing.T) {
   337		for _, tc := range metaTests {
   338			// Verify that QuoteMeta returns the expected string.
   339			quoted := QuoteMeta(tc.pattern)
   340			if quoted != tc.output {
   341				t.Errorf("QuoteMeta(`%s`) = `%s`; want `%s`",
   342					tc.pattern, quoted, tc.output)
   343				continue
   344			}
   345	
   346			// Verify that the quoted string is in fact treated as expected
   347			// by Compile -- i.e. that it matches the original, unquoted string.
   348			if tc.pattern != "" {
   349				re, err := Compile(quoted)
   350				if err != nil {
   351					t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err)
   352					continue
   353				}
   354				src := "abc" + tc.pattern + "def"
   355				repl := "xyz"
   356				replaced := re.ReplaceAllString(src, repl)
   357				expected := "abcxyzdef"
   358				if replaced != expected {
   359					t.Errorf("QuoteMeta(`%s`).Replace(`%s`,`%s`) = `%s`; want `%s`",
   360						tc.pattern, src, repl, replaced, expected)
   361				}
   362			}
   363		}
   364	}
   365	
   366	func TestLiteralPrefix(t *testing.T) {
   367		for _, tc := range metaTests {
   368			// Literal method needs to scan the pattern.
   369			re := MustCompile(tc.pattern)
   370			str, complete := re.LiteralPrefix()
   371			if complete != tc.isLiteral {
   372				t.Errorf("LiteralPrefix(`%s`) = %t; want %t", tc.pattern, complete, tc.isLiteral)
   373			}
   374			if str != tc.literal {
   375				t.Errorf("LiteralPrefix(`%s`) = `%s`; want `%s`", tc.pattern, str, tc.literal)
   376			}
   377		}
   378	}
   379	
   380	type subexpCase struct {
   381		input string
   382		num   int
   383		names []string
   384	}
   385	
   386	var subexpCases = []subexpCase{
   387		{``, 0, nil},
   388		{`.*`, 0, nil},
   389		{`abba`, 0, nil},
   390		{`ab(b)a`, 1, []string{"", ""}},
   391		{`ab(.*)a`, 1, []string{"", ""}},
   392		{`(.*)ab(.*)a`, 2, []string{"", "", ""}},
   393		{`(.*)(ab)(.*)a`, 3, []string{"", "", "", ""}},
   394		{`(.*)((a)b)(.*)a`, 4, []string{"", "", "", "", ""}},
   395		{`(.*)(\(ab)(.*)a`, 3, []string{"", "", "", ""}},
   396		{`(.*)(\(a\)b)(.*)a`, 3, []string{"", "", "", ""}},
   397		{`(?P<foo>.*)(?P<bar>(a)b)(?P<foo>.*)a`, 4, []string{"", "foo", "bar", "", "foo"}},
   398	}
   399	
   400	func TestSubexp(t *testing.T) {
   401		for _, c := range subexpCases {
   402			re := MustCompile(c.input)
   403			n := re.NumSubexp()
   404			if n != c.num {
   405				t.Errorf("%q: NumSubexp = %d, want %d", c.input, n, c.num)
   406				continue
   407			}
   408			names := re.SubexpNames()
   409			if len(names) != 1+n {
   410				t.Errorf("%q: len(SubexpNames) = %d, want %d", c.input, len(names), n)
   411				continue
   412			}
   413			if c.names != nil {
   414				for i := 0; i < 1+n; i++ {
   415					if names[i] != c.names[i] {
   416						t.Errorf("%q: SubexpNames[%d] = %q, want %q", c.input, i, names[i], c.names[i])
   417					}
   418				}
   419			}
   420		}
   421	}
   422	
   423	var splitTests = []struct {
   424		s   string
   425		r   string
   426		n   int
   427		out []string
   428	}{
   429		{"foo:and:bar", ":", -1, []string{"foo", "and", "bar"}},
   430		{"foo:and:bar", ":", 1, []string{"foo:and:bar"}},
   431		{"foo:and:bar", ":", 2, []string{"foo", "and:bar"}},
   432		{"foo:and:bar", "foo", -1, []string{"", ":and:bar"}},
   433		{"foo:and:bar", "bar", -1, []string{"foo:and:", ""}},
   434		{"foo:and:bar", "baz", -1, []string{"foo:and:bar"}},
   435		{"baabaab", "a", -1, []string{"b", "", "b", "", "b"}},
   436		{"baabaab", "a*", -1, []string{"b", "b", "b"}},
   437		{"baabaab", "ba*", -1, []string{"", "", "", ""}},
   438		{"foobar", "f*b*", -1, []string{"", "o", "o", "a", "r"}},
   439		{"foobar", "f+.*b+", -1, []string{"", "ar"}},
   440		{"foobooboar", "o{2}", -1, []string{"f", "b", "boar"}},
   441		{"a,b,c,d,e,f", ",", 3, []string{"a", "b", "c,d,e,f"}},
   442		{"a,b,c,d,e,f", ",", 0, nil},
   443		{",", ",", -1, []string{"", ""}},
   444		{",,,", ",", -1, []string{"", "", "", ""}},
   445		{"", ",", -1, []string{""}},
   446		{"", ".*", -1, []string{""}},
   447		{"", ".+", -1, []string{""}},
   448		{"", "", -1, []string{}},
   449		{"foobar", "", -1, []string{"f", "o", "o", "b", "a", "r"}},
   450		{"abaabaccadaaae", "a*", 5, []string{"", "b", "b", "c", "cadaaae"}},
   451		{":x:y:z:", ":", -1, []string{"", "x", "y", "z", ""}},
   452	}
   453	
   454	func TestSplit(t *testing.T) {
   455		for i, test := range splitTests {
   456			re, err := Compile(test.r)
   457			if err != nil {
   458				t.Errorf("#%d: %q: compile error: %s", i, test.r, err.Error())
   459				continue
   460			}
   461	
   462			split := re.Split(test.s, test.n)
   463			if !reflect.DeepEqual(split, test.out) {
   464				t.Errorf("#%d: %q: got %q; want %q", i, test.r, split, test.out)
   465			}
   466	
   467			if QuoteMeta(test.r) == test.r {
   468				strsplit := strings.SplitN(test.s, test.r, test.n)
   469				if !reflect.DeepEqual(split, strsplit) {
   470					t.Errorf("#%d: Split(%q, %q, %d): regexp vs strings mismatch\nregexp=%q\nstrings=%q", i, test.s, test.r, test.n, split, strsplit)
   471				}
   472			}
   473		}
   474	}
   475	
   476	func BenchmarkLiteral(b *testing.B) {
   477		x := strings.Repeat("x", 50) + "y"
   478		b.StopTimer()
   479		re := MustCompile("y")
   480		b.StartTimer()
   481		for i := 0; i < b.N; i++ {
   482			if !re.MatchString(x) {
   483				b.Fatalf("no match!")
   484			}
   485		}
   486	}
   487	
   488	func BenchmarkNotLiteral(b *testing.B) {
   489		x := strings.Repeat("x", 50) + "y"
   490		b.StopTimer()
   491		re := MustCompile(".y")
   492		b.StartTimer()
   493		for i := 0; i < b.N; i++ {
   494			if !re.MatchString(x) {
   495				b.Fatalf("no match!")
   496			}
   497		}
   498	}
   499	
   500	func BenchmarkMatchClass(b *testing.B) {
   501		b.StopTimer()
   502		x := strings.Repeat("xxxx", 20) + "w"
   503		re := MustCompile("[abcdw]")
   504		b.StartTimer()
   505		for i := 0; i < b.N; i++ {
   506			if !re.MatchString(x) {
   507				b.Fatalf("no match!")
   508			}
   509		}
   510	}
   511	
   512	func BenchmarkMatchClass_InRange(b *testing.B) {
   513		b.StopTimer()
   514		// 'b' is between 'a' and 'c', so the charclass
   515		// range checking is no help here.
   516		x := strings.Repeat("bbbb", 20) + "c"
   517		re := MustCompile("[ac]")
   518		b.StartTimer()
   519		for i := 0; i < b.N; i++ {
   520			if !re.MatchString(x) {
   521				b.Fatalf("no match!")
   522			}
   523		}
   524	}
   525	
   526	func BenchmarkReplaceAll(b *testing.B) {
   527		x := "abcdefghijklmnopqrstuvwxyz"
   528		b.StopTimer()
   529		re := MustCompile("[cjrw]")
   530		b.StartTimer()
   531		for i := 0; i < b.N; i++ {
   532			re.ReplaceAllString(x, "")
   533		}
   534	}
   535	
   536	func BenchmarkAnchoredLiteralShortNonMatch(b *testing.B) {
   537		b.StopTimer()
   538		x := []byte("abcdefghijklmnopqrstuvwxyz")
   539		re := MustCompile("^zbc(d|e)")
   540		b.StartTimer()
   541		for i := 0; i < b.N; i++ {
   542			re.Match(x)
   543		}
   544	}
   545	
   546	func BenchmarkAnchoredLiteralLongNonMatch(b *testing.B) {
   547		b.StopTimer()
   548		x := []byte("abcdefghijklmnopqrstuvwxyz")
   549		for i := 0; i < 15; i++ {
   550			x = append(x, x...)
   551		}
   552		re := MustCompile("^zbc(d|e)")
   553		b.StartTimer()
   554		for i := 0; i < b.N; i++ {
   555			re.Match(x)
   556		}
   557	}
   558	
   559	func BenchmarkAnchoredShortMatch(b *testing.B) {
   560		b.StopTimer()
   561		x := []byte("abcdefghijklmnopqrstuvwxyz")
   562		re := MustCompile("^.bc(d|e)")
   563		b.StartTimer()
   564		for i := 0; i < b.N; i++ {
   565			re.Match(x)
   566		}
   567	}
   568	
   569	func BenchmarkAnchoredLongMatch(b *testing.B) {
   570		b.StopTimer()
   571		x := []byte("abcdefghijklmnopqrstuvwxyz")
   572		for i := 0; i < 15; i++ {
   573			x = append(x, x...)
   574		}
   575		re := MustCompile("^.bc(d|e)")
   576		b.StartTimer()
   577		for i := 0; i < b.N; i++ {
   578			re.Match(x)
   579		}
   580	}

View as plain text