| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- package strings
- import "unicode/utf8"
- // IndexNotByte is similar with strings.IndexByte but showing the opposite behavior.
- func IndexNotByte(s string, c byte) int {
- n := len(s)
- for i := 0; i < n; i++ {
- if s[i] != c {
- return i
- }
- }
- return -1
- }
- // LastIndexNotByte is similar with strings.LastIndexByte but showing the opposite behavior.
- func LastIndexNotByte(s string, c byte) int {
- for i := len(s) - 1; i >= 0; i-- {
- if s[i] != c {
- return i
- }
- }
- return -1
- }
- type asciiSet [8]uint32
- func (as *asciiSet) notContains(c byte) bool {
- return (as[c>>5] & (1 << uint(c&31))) == 0
- }
- func makeASCIISet(chars string) (as asciiSet, ok bool) {
- for i := 0; i < len(chars); i++ {
- c := chars[i]
- if c >= utf8.RuneSelf {
- return as, false
- }
- as[c>>5] |= 1 << uint(c&31)
- }
- return as, true
- }
- // IndexNotAny is similar with strings.IndexAny but showing the opposite behavior.
- func IndexNotAny(s, chars string) int {
- if len(chars) > 0 {
- if len(s) > 8 {
- if as, isASCII := makeASCIISet(chars); isASCII {
- for i := 0; i < len(s); i++ {
- if as.notContains(s[i]) {
- return i
- }
- }
- return -1
- }
- }
- LabelFirstLoop:
- for i, c := range s {
- for j, m := range chars {
- if c != m && j == len(chars)-1 {
- return i
- } else if c != m {
- continue
- } else {
- continue LabelFirstLoop
- }
- }
- }
- }
- return -1
- }
- // LastIndexNotAny is similar with strings.LastIndexAny but showing the opposite behavior.
- func LastIndexNotAny(s, chars string) int {
- if len(chars) > 0 {
- if len(s) > 8 {
- if as, isASCII := makeASCIISet(chars); isASCII {
- for i := len(s) - 1; i >= 0; i-- {
- if as.notContains(s[i]) {
- return i
- }
- }
- return -1
- }
- }
- LabelFirstLoop:
- for i := len(s); i > 0; {
- r, size := utf8.DecodeLastRuneInString(s[:i])
- i -= size
- for j, m := range chars {
- if r != m && j == len(chars)-1 {
- return i
- } else if r != m {
- continue
- } else {
- continue LabelFirstLoop
- }
- }
- }
- }
- return -1
- }
|