regexp: add Split

As discussed in issue 2672 and on golang-nuts, this CL adds a Split() method
to regexp. It is based on returning the "opposite" of FindAllString() so that
the returned substrings are everything not matched by the expression.

See: https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/xodBZh9Lh2E

Fixes #2762.

R=remyoudompheng, r, rsc
CC=golang-dev
https://golang.org/cl/6846048
diff --git a/src/pkg/regexp/all_test.go b/src/pkg/regexp/all_test.go
index f7b41a6..dd2ed04 100644
--- a/src/pkg/regexp/all_test.go
+++ b/src/pkg/regexp/all_test.go
@@ -5,6 +5,7 @@
 package regexp
 
 import (
+	"reflect"
 	"strings"
 	"testing"
 )
@@ -416,6 +417,59 @@
 	}
 }
 
+var splitTests = []struct {
+	s   string
+	r   string
+	n   int
+	out []string
+}{
+	{"foo:and:bar", ":", -1, []string{"foo", "and", "bar"}},
+	{"foo:and:bar", ":", 1, []string{"foo:and:bar"}},
+	{"foo:and:bar", ":", 2, []string{"foo", "and:bar"}},
+	{"foo:and:bar", "foo", -1, []string{"", ":and:bar"}},
+	{"foo:and:bar", "bar", -1, []string{"foo:and:", ""}},
+	{"foo:and:bar", "baz", -1, []string{"foo:and:bar"}},
+	{"baabaab", "a", -1, []string{"b", "", "b", "", "b"}},
+	{"baabaab", "a*", -1, []string{"b", "b", "b"}},
+	{"baabaab", "ba*", -1, []string{"", "", "", ""}},
+	{"foobar", "f*b*", -1, []string{"", "o", "o", "a", "r"}},
+	{"foobar", "f+.*b+", -1, []string{"", "ar"}},
+	{"foobooboar", "o{2}", -1, []string{"f", "b", "boar"}},
+	{"a,b,c,d,e,f", ",", 3, []string{"a", "b", "c,d,e,f"}},
+	{"a,b,c,d,e,f", ",", 0, nil},
+	{",", ",", -1, []string{"", ""}},
+	{",,,", ",", -1, []string{"", "", "", ""}},
+	{"", ",", -1, []string{""}},
+	{"", ".*", -1, []string{""}},
+	{"", ".+", -1, []string{""}},
+	{"", "", -1, []string{}},
+	{"foobar", "", -1, []string{"f", "o", "o", "b", "a", "r"}},
+	{"abaabaccadaaae", "a*", 5, []string{"", "b", "b", "c", "cadaaae"}},
+	{":x:y:z:", ":", -1, []string{"", "x", "y", "z", ""}},
+}
+
+func TestSplit(t *testing.T) {
+	for i, test := range splitTests {
+		re, err := Compile(test.r)
+		if err != nil {
+			t.Errorf("#%d: %q: compile error: %s", i, test.r, err.Error())
+			continue
+		}
+
+		split := re.Split(test.s, test.n)
+		if !reflect.DeepEqual(split, test.out) {
+			t.Errorf("#%d: %q: got %q; want %q", i, test.r, split, test.out)
+		}
+
+		if QuoteMeta(test.r) == test.r {
+			strsplit := strings.SplitN(test.s, test.r, test.n)
+			if !reflect.DeepEqual(split, strsplit) {
+				t.Errorf("#%d: Split(%q, %q, %d): regexp vs strings mismatch\nregexp=%q\nstrings=%q", i, test.s, test.r, test.n, split, strsplit)
+			}
+		}
+	}
+}
+
 func BenchmarkLiteral(b *testing.B) {
 	x := strings.Repeat("x", 50) + "y"
 	b.StopTimer()