Add a ReplaceAll method to Regexp.
APPROVED=r,rsc
DELTA=189 (187 added, 0 deleted, 2 changed)
OCL=30205
CL=30517
diff --git a/src/pkg/regexp/all_test.go b/src/pkg/regexp/all_test.go
index a9f2758..23c2200 100644
--- a/src/pkg/regexp/all_test.go
+++ b/src/pkg/regexp/all_test.go
@@ -233,3 +233,125 @@
matchFunctionTest(t, test.re, test.text, test.match)
}
}
+
+type ReplaceTest struct {
+ pattern, replacement, input, output string;
+}
+
+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"},
+
+ // 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"},
+
+ // 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"},
+
+ // 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", "", ""},
+
+ // 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"},
+}
+
+func TestReplaceAll(t *testing.T) {
+ for i, tc := range replaceTests {
+ re, err := Compile(tc.pattern);
+ if err != nil {
+ t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err);
+ continue;
+ }
+ actual := re.ReplaceAll(tc.input, tc.replacement);
+ if actual != tc.output {
+ t.Errorf("%q.Replace(%q,%q) = %q; want %q",
+ tc.pattern, tc.input, tc.replacement, actual, tc.output);
+ }
+ }
+}
+
+type QuoteMetaTest struct {
+ pattern, output string;
+}
+
+var quoteMetaTests = []QuoteMetaTest {
+ QuoteMetaTest{``, ``},
+ QuoteMetaTest{`foo`, `foo`},
+ QuoteMetaTest{`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[{\]}\\\|,<\.>/\?~`},
+}
+
+func TestQuoteMeta(t *testing.T) {
+ for i, tc := range quoteMetaTests {
+ // Verify that QuoteMeta returns the expected string.
+ quoted := QuoteMeta(tc.pattern);
+ if quoted != tc.output {
+ t.Errorf("QuoteMeta(`%s`) = `%s`; want `%s`",
+ tc.pattern, quoted, tc.output);
+ continue;
+ }
+
+ // Verify that the quoted string is in fact treated as expected
+ // by Compile -- i.e. that it matches the original, unquoted string.
+ if tc.pattern != "" {
+ re, err := Compile(quoted);
+ if err != nil {
+ t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err);
+ continue;
+ }
+ src := "abc" + tc.pattern + "def";
+ repl := "xyz";
+ replaced := re.ReplaceAll(src, repl);
+ expected := "abcxyzdef";
+ if replaced != expected {
+ t.Errorf("QuoteMeta(`%s`).Replace(`%s`,`%s`) = `%s`; want `%s`",
+ tc.pattern, src, repl, replaced, expected);
+ }
+ }
+ }
+}
+