github.com/benhoyt/goawk@v1.8.1/internal/strutil/strutil.go (about) 1 // Package strutil provides some miscellaneous string functions. 2 // 3 package strutil 4 5 import ( 6 "strings" 7 "unicode" 8 "unicode/utf8" 9 ) 10 11 var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1} 12 13 // TrimSpace returns a slice of the string s, with all leading and 14 // trailing white space removed, as defined by Unicode. (It behaves 15 // the same as Go's strings.TrimSpace, but has a fast path for ASCII 16 // strings so is much faster for common cases.) 17 func TrimSpace(s string) string { 18 // Fast path for ASCII: look for the first ASCII non-space byte 19 start := 0 20 for ; start < len(s); start++ { 21 c := s[start] 22 if c >= utf8.RuneSelf { 23 // If we run into a non-ASCII byte, fall back to the 24 // slower unicode-aware method on the remaining bytes 25 return strings.TrimFunc(s[start:], unicode.IsSpace) 26 } 27 if asciiSpace[c] == 0 { 28 break 29 } 30 } 31 32 // Now look for the first ASCII non-space byte from the end 33 stop := len(s) 34 for ; stop > start; stop-- { 35 c := s[stop-1] 36 if c >= utf8.RuneSelf { 37 return strings.TrimFunc(s[start:stop], unicode.IsSpace) 38 } 39 if asciiSpace[c] == 0 { 40 break 41 } 42 } 43 44 // At this point s[start:stop] starts and ends with an ASCII 45 // non-space bytes, so we're done. Non-ASCII cases have already 46 // been handled above. 47 return s[start:stop] 48 } 49 50 // IsASCIISpace returns true if c represents an ASCII whitespace byte. 51 func IsASCIISpace(c byte) bool { 52 return asciiSpace[c] != 0 53 }