mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
bytes, strings: IndexOfAny
+ first use in go/doc R=r CC=golang-dev https://golang.org/cl/781041
This commit is contained in:
parent
9e481e2905
commit
d0ffee8abf
5 changed files with 102 additions and 28 deletions
|
|
@ -125,6 +125,21 @@ func LastIndex(s, sep []byte) int {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IndexAny returns the index of the first instance of any byte
|
||||||
|
// from bytes in s, or -1 if no byte from bytes is present in s.
|
||||||
|
func IndexAny(s, bytes []byte) int {
|
||||||
|
if len(bytes) > 0 {
|
||||||
|
for i, b := range s {
|
||||||
|
for _, m := range bytes {
|
||||||
|
if b == m {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
// Generic split: splits after each instance of sep,
|
// Generic split: splits after each instance of sep,
|
||||||
// including sepSave bytes of sep in the subarrays.
|
// including sepSave bytes of sep in the subarrays.
|
||||||
func genSplit(s, sep []byte, sepSave, n int) [][]byte {
|
func genSplit(s, sep []byte, sepSave, n int) [][]byte {
|
||||||
|
|
|
||||||
|
|
@ -72,16 +72,19 @@ func TestCompare(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var indextests = []BinOpTest{
|
var indexTests = []BinOpTest{
|
||||||
BinOpTest{"", "", 0},
|
BinOpTest{"", "", 0},
|
||||||
BinOpTest{"a", "", 0},
|
|
||||||
BinOpTest{"", "a", -1},
|
BinOpTest{"", "a", -1},
|
||||||
BinOpTest{"abc", "abc", 0},
|
BinOpTest{"", "foo", -1},
|
||||||
BinOpTest{"ab", "abc", -1},
|
BinOpTest{"fo", "foo", -1},
|
||||||
BinOpTest{"abc", "bc", 1},
|
BinOpTest{"foo", "foo", 0},
|
||||||
BinOpTest{"x", "ab", -1},
|
BinOpTest{"oofofoofooo", "f", 2},
|
||||||
// one-byte tests for IndexByte
|
BinOpTest{"oofofoofooo", "foo", 4},
|
||||||
BinOpTest{"ab", "x", -1},
|
BinOpTest{"barfoobarfoo", "foo", 3},
|
||||||
|
BinOpTest{"foo", "", 0},
|
||||||
|
BinOpTest{"foo", "o", 1},
|
||||||
|
BinOpTest{"abcABCabc", "A", 3},
|
||||||
|
// cases with one byte strings - test IndexByte and special case in Index()
|
||||||
BinOpTest{"", "a", -1},
|
BinOpTest{"", "a", -1},
|
||||||
BinOpTest{"x", "a", -1},
|
BinOpTest{"x", "a", -1},
|
||||||
BinOpTest{"x", "x", 0},
|
BinOpTest{"x", "x", 0},
|
||||||
|
|
@ -91,19 +94,54 @@ var indextests = []BinOpTest{
|
||||||
BinOpTest{"abc", "x", -1},
|
BinOpTest{"abc", "x", -1},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIndex(t *testing.T) {
|
var lastIndexTests = []BinOpTest{
|
||||||
for _, tt := range indextests {
|
BinOpTest{"", "", 0},
|
||||||
a := []byte(tt.a)
|
BinOpTest{"", "a", -1},
|
||||||
b := []byte(tt.b)
|
BinOpTest{"", "foo", -1},
|
||||||
pos := Index(a, b)
|
BinOpTest{"fo", "foo", -1},
|
||||||
if pos != tt.i {
|
BinOpTest{"foo", "foo", 0},
|
||||||
t.Errorf(`Index(%q, %q) = %v`, tt.a, tt.b, pos)
|
BinOpTest{"foo", "f", 0},
|
||||||
|
BinOpTest{"oofofoofooo", "f", 7},
|
||||||
|
BinOpTest{"oofofoofooo", "foo", 7},
|
||||||
|
BinOpTest{"barfoobarfoo", "foo", 9},
|
||||||
|
BinOpTest{"foo", "", 3},
|
||||||
|
BinOpTest{"foo", "o", 2},
|
||||||
|
BinOpTest{"abcABCabc", "A", 3},
|
||||||
|
BinOpTest{"abcABCabc", "a", 6},
|
||||||
|
}
|
||||||
|
|
||||||
|
var indexAnyTests = []BinOpTest{
|
||||||
|
BinOpTest{"", "", -1},
|
||||||
|
BinOpTest{"", "a", -1},
|
||||||
|
BinOpTest{"", "abc", -1},
|
||||||
|
BinOpTest{"a", "", -1},
|
||||||
|
BinOpTest{"a", "a", 0},
|
||||||
|
BinOpTest{"aaa", "a", 0},
|
||||||
|
BinOpTest{"abc", "xyz", -1},
|
||||||
|
BinOpTest{"abc", "xcz", 2},
|
||||||
|
BinOpTest{"aRegExp*", ".(|)*+?^$[]", 7},
|
||||||
|
BinOpTest{dots + dots + dots, " ", -1},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute f on each test case. funcName should be the name of f; it's used
|
||||||
|
// in failure reports.
|
||||||
|
func runIndexTests(t *testing.T, f func(s, sep []byte) int, funcName string, testCases []BinOpTest) {
|
||||||
|
for _, test := range testCases {
|
||||||
|
a := []byte(test.a)
|
||||||
|
b := []byte(test.b)
|
||||||
|
actual := f(a, b)
|
||||||
|
if actual != test.i {
|
||||||
|
t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, b, actual, test.i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) }
|
||||||
|
func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
|
||||||
|
func TestIndexAny(t *testing.T) { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) }
|
||||||
|
|
||||||
func TestIndexByte(t *testing.T) {
|
func TestIndexByte(t *testing.T) {
|
||||||
for _, tt := range indextests {
|
for _, tt := range indexTests {
|
||||||
if len(tt.b) != 1 {
|
if len(tt.b) != 1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -564,15 +565,7 @@ func (doc *docReader) newDoc(importpath string, filenames []string) *PackageDoc
|
||||||
|
|
||||||
// Does s look like a regular expression?
|
// Does s look like a regular expression?
|
||||||
func isRegexp(s string) bool {
|
func isRegexp(s string) bool {
|
||||||
metachars := ".(|)*+?^$[]"
|
return strings.IndexAny(s, ".(|)*+?^$[]") >= 0
|
||||||
for _, c := range s {
|
|
||||||
for _, m := range metachars {
|
|
||||||
if c == m {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,21 @@ func LastIndex(s, sep string) int {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IndexAny returns the index of the first instance of any Unicode code point
|
||||||
|
// from chars in s, or -1 if no Unicode code point from chars is present in s.
|
||||||
|
func IndexAny(s, chars string) int {
|
||||||
|
if len(chars) > 0 {
|
||||||
|
for i, c := range s {
|
||||||
|
for _, m := range chars {
|
||||||
|
if c == m {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
// Generic split: splits after each instance of sep,
|
// Generic split: splits after each instance of sep,
|
||||||
// including sepSave bytes of sep in the subarrays.
|
// including sepSave bytes of sep in the subarrays.
|
||||||
func genSplit(s, sep string, sepSave, n int) []string {
|
func genSplit(s, sep string, sepSave, n int) []string {
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,20 @@ var lastIndexTests = []IndexTest{
|
||||||
IndexTest{"abcABCabc", "a", 6},
|
IndexTest{"abcABCabc", "a", 6},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var indexAnyTests = []IndexTest{
|
||||||
|
IndexTest{"", "", -1},
|
||||||
|
IndexTest{"", "a", -1},
|
||||||
|
IndexTest{"", "abc", -1},
|
||||||
|
IndexTest{"a", "", -1},
|
||||||
|
IndexTest{"a", "a", 0},
|
||||||
|
IndexTest{"aaa", "a", 0},
|
||||||
|
IndexTest{"abc", "xyz", -1},
|
||||||
|
IndexTest{"abc", "xcz", 2},
|
||||||
|
IndexTest{"a☺b☻c☹d", "uvw☻xyz", 2 + len("☺")},
|
||||||
|
IndexTest{"aRegExp*", ".(|)*+?^$[]", 7},
|
||||||
|
IndexTest{dots + dots + dots, " ", -1},
|
||||||
|
}
|
||||||
|
|
||||||
// Execute f on each test case. funcName should be the name of f; it's used
|
// Execute f on each test case. funcName should be the name of f; it's used
|
||||||
// in failure reports.
|
// in failure reports.
|
||||||
func runIndexTests(t *testing.T, f func(s, sep string) int, funcName string, testCases []IndexTest) {
|
func runIndexTests(t *testing.T, f func(s, sep string) int, funcName string, testCases []IndexTest) {
|
||||||
|
|
@ -83,10 +97,9 @@ func runIndexTests(t *testing.T, f func(s, sep string) int, funcName string, tes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) }
|
func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) }
|
||||||
|
|
||||||
func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
|
func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
|
||||||
|
func TestIndexAny(t *testing.T) { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) }
|
||||||
|
|
||||||
type ExplodeTest struct {
|
type ExplodeTest struct {
|
||||||
s string
|
s string
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue