1 Star 1 Fork 0

D10.天地弦 / gobase

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
strings.go 49.60 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529
package gobase
import (
"bytes"
"crypto/md5"
"encoding/binary"
"fmt"
"io"
"math"
"math/rand"
"regexp"
"runtime"
"sort"
"strconv"
"strings"
"time"
"unicode"
"unicode/utf8"
"unsafe"
)
const (
EMPTY_STRING string = ""
QUOTECHR = '"'
)
var (
ErrUnsupported = fmt.Errorf("unsupported")
)
/*
*
字符集 字数 Unicode 编码
基本汉字 20902字 4E00-9FA5 // 一 ~ 龥 (简繁)
基本汉字补充 90字 9FA6-9FFF
扩展A 6592字 3400-4DBF
扩展B 42720字 20000-2A6DF
扩展C 4153字 2A700-2B738
扩展D 222字 2B740-2B81D
扩展E 5762字 2B820-2CEA1
扩展F 7473字 2CEB0-2EBE0
扩展G 4939字 30000-3134A
康熙部首 214字 2F00-2FD5
部首扩展 115字 2E80-2EF3
兼容汉字 477字 F900-FAD9
兼容扩展 542字 2F800-2FA1D
PUA(GBK)部件 81字 E815-E86F
部件扩展 452字 E400-E5E8
PUA增补 207字 E600-E6CF
汉字笔画 36字 31C0-31E3
汉字结构 12字 2FF0-2FFB
汉语注音 43字 3105-312F
注音扩展 22字 31A0-31BA
〇 1字 3007
*/
func IsChineseChar(c rune) bool {
return c >= 0x4E00 && c <= 0x9FA5
}
/*
*
包含中文和英文
*/
func ReplaceNonChineseChar(s string, newchr rune) string {
rs := []rune(s)
rval := make([]rune, 0, len(rs))
for _, chr := range rs {
if IsAsciiPrintChar(chr) || IsChineseChar(chr) {
rval = append(rval, chr)
} else {
rval = append(rval, newchr)
}
}
return string(rval)
}
/*
*
包含中文和英文
*/
func DelNonChineseChar(s string) string {
rs := []rune(s)
rval := make([]rune, 0, len(rs))
for _, chr := range rs {
if IsAsciiPrintChar(chr) || IsChineseChar(chr) {
rval = append(rval, chr)
}
}
return string(rval)
}
func DelNonChineseCharEx(s string, splitchar rune) string {
idx := 0
rs := []rune(s)
rval := make([]rune, 0, len(rs))
for _, chr := range rs {
if IsAsciiPrintChar(chr) || IsChineseChar(chr) {
rval = append(rval, chr)
idx++
} else {
if idx > 0 {
rval = append(rval, splitchar)
idx = 0
}
}
}
return string(rval)
}
func ReplaceNonAsciiChar(s []byte, newchr byte) string {
rval := make([]byte, 0, len(s))
for _, chr := range s {
if IsAsciiPrintByte(chr) {
rval = append(rval, chr)
} else {
rval = append(rval, newchr)
}
}
return string(rval)
}
func DelNonAsciiChar(s []byte) string {
rval := make([]byte, 0, len(s))
for _, chr := range s {
if IsAsciiPrintByte(chr) {
rval = append(rval, chr)
}
}
return string(rval)
}
func JoinIfNoEmpty(chk string, sep string, args ...string) string {
if len(chk) == 0 {
return ""
} else {
return strings.Join(args, sep)
}
}
func DelNonAsciiCharEx(s []byte, splitchar byte) string {
idx := 0
rval := make([]byte, 0, len(s))
for _, chr := range s {
if IsAsciiPrintByte(chr) {
rval = append(rval, chr)
idx++
} else {
if idx > 0 {
rval = append(rval, splitchar)
idx = 0
}
}
}
return string(rval)
}
/*
FormatFloatVlst
*/
func FormatFloatVlst(fmtstr string, singalw int, totalwidth int, args ...float64) string {
strBuf := make([]byte, 0, len(args)*singalw)
for _, v := range args {
s0 := AddPrefixForWidth(fmt.Sprintf(fmtstr, v), singalw, " ")
strBuf = append(strBuf, []byte(s0)...)
}
s1 := string(strBuf)
if totalwidth > 0 {
s1 = AddSuffixForWidth(s1, totalwidth, " ")
}
return s1
}
func ReplaceNonPrintChar(s string, newchr rune) string {
strs := []rune(s)
rval := make([]rune, 0, len(strs))
for _, chr := range strs {
if unicode.IsPrint(chr) || (chr == 10 || chr == 13 || chr == '\t') {
rval = append(rval, chr)
} else {
rval = append(rval, newchr)
}
}
return string(rval)
}
func DelNonPrintChar(s string) string {
strs := []rune(s)
rval := make([]rune, 0, len(strs))
for _, chr := range strs {
if unicode.IsPrint(chr) || (chr == 10 || chr == 13 || chr == '\t') {
rval = append(rval, chr)
}
}
return string(rval)
}
func MD5(str string) string {
w := md5.New()
io.WriteString(w, str)
md5Buf := w.Sum(nil)
md5str := fmt.Sprintf("%x", md5Buf)
return md5str
}
func HashStr(str string) int64 {
var sum int64 = 0
for i := 0; i < len(str); i++ {
sum += int64(str[i])
}
return sum
}
func MD5Buf(data []byte) string {
w := md5.New()
w.Write(data)
md5str := fmt.Sprintf("%x", w.Sum(nil))
return md5str
}
// 如果是简单类型请不要使用该函数
// 可以使用GetStrValue函数代替
func ObjectHexAddr(v interface{}) string {
return fmt.Sprintf("%p", v)
}
/*
*
StrToNumSuffix("100K", 1024)
OK:
1M, 100K, 1G, 15
FAIL:
1KB, 1.4K 100m15k
*/
func StrToNumSuffix(str string, mult int64) int64 {
num := int64(1)
if len(str) > 1 {
switch str[len(str)-1] {
case 'G', 'g':
num *= mult
fallthrough
case 'M', 'm':
num *= mult
fallthrough
case 'K', 'k':
num *= mult
str = str[0 : len(str)-1]
}
}
parsed, _ := strconv.Atoi(str)
return int64(parsed) * num
}
/*
**
HumanSizeToSize("1024KB")
*/
func HumanSizeStrToSize(str string) int64 {
if len(str) == 0 {
return 0
}
num, suffix := SplitNumericAndRemain(str)
suffix = Trim(suffix)
suffix = strings.ToUpper(suffix)
if suffix == "KB" || suffix == "K" {
return int64(StrToFloat64Def(num, 0) * 1024)
}
if suffix == "MB" || suffix == "M" {
return int64(StrToFloat64Def(num, 0) * float64(SIZE_MB))
}
if suffix == "GB" || suffix == "G" {
return int64(StrToFloat64Def(num, 0) * float64(SIZE_GB))
}
if suffix == "TB" || suffix == "T" {
return int64(StrToFloat64Def(num, 0) * float64(SIZE_TB))
}
return 0
}
/*
**
00:00-07:00,08:00-10:00,11:00-12:00
*/
func IsInMultiSection(exp, s string) string {
itms := strings.Split(exp, ",")
if len(itms) == 1 {
itms = strings.Split(exp, ";")
}
if len(itms) == 1 {
itms = strings.Split(exp, " ")
}
for i := 0; i < len(itms); i++ {
if IsInSection(itms[i], s) {
return itms[i]
}
}
return ""
}
/*
**
00:00-07:00
*/
func IsInSection(exp, s string) bool {
exp = Trim(exp)
if len(exp) == 0 {
return false
}
itms := strings.SplitN(exp, "-", 2)
if len(itms) == 1 {
itms = strings.SplitN(exp, "~", 2)
}
if len(itms) == 1 {
return false
}
return s >= itms[0] && s <= itms[1]
}
func LastChrCnt(s string, c byte) int {
r := 0
for i := len(s) - 1; i >= 0; i-- {
if s[i] == c {
r++
} else {
return r
}
}
return r
}
// Copy From DxValue.Record
func UnEscapeJSONStr(bvalue []byte) []byte {
buf := make([]byte, 0, 256)
blen := len(bvalue)
i := 0
unicodeidx := 0
escapeType := uint8(0) //0 normal,1 json\escapin,2 unicode escape, 3 % url escape
for i < blen {
switch escapeType {
case 1: //json escapin
escapeType = 0
switch bvalue[i] {
case 'a':
buf = append(buf, '\a')
case 'b':
buf = append(buf, '\b')
case 'f':
buf = append(buf, '\f')
case 'n':
buf = append(buf, '\n')
case 'r':
buf = append(buf, '\r')
case 't':
buf = append(buf, '\t')
case 'v':
buf = append(buf, '\v')
case '\\':
buf = append(buf, '\\')
case '"':
buf = append(buf, '"')
case '\'':
buf = append(buf, '\'')
case '/':
buf = append(buf, '/')
case 'u':
escapeType = 2 // unicode decode
unicodeidx = i
default:
buf = append(buf, '\\', bvalue[i])
}
case 2: //unicode decode
if (bvalue[i] >= '0' && bvalue[i] <= '9' || bvalue[i] >= 'a' && bvalue[i] <= 'f' ||
bvalue[i] >= 'A' && bvalue[i] <= 'F') && i-unicodeidx <= 4 {
//还是正常的Unicode字符,4个字符为一组
//escapeType = 2
} else {
unicodestr := FastByte2String(bvalue[unicodeidx+1 : i])
if arune, err := strconv.ParseInt(unicodestr, 16, 32); err == nil {
l := len(buf)
buf = append(buf, 0, 0, 0, 0)
runelen := utf8.EncodeRune(buf[l:l+4], rune(arune))
buf = buf[:l+runelen]
} else {
buf = append(buf, bvalue[unicodeidx:i]...)
}
escapeType = 0
continue
}
case 3: //url escape
for j := 0; j < 3; j++ {
if (bvalue[j+i] >= '0' && bvalue[j+i] <= '9' || bvalue[i+j] >= 'a' && bvalue[i+j] <= 'f' ||
bvalue[j+i] >= 'A' && bvalue[j+i] <= 'F') && j < 2 {
//还是正常的Byte字符,2个字符为一组
//escapeType = 2
} else {
bytestr := FastByte2String(bvalue[i : i+j])
if abyte, err := strconv.ParseInt(bytestr, 16, 32); err == nil {
buf = append(buf, byte(abyte))
} else {
buf = append(buf, bvalue[i-1:i+j]...) //%要加上
}
escapeType = 0
i += j - 1
break
}
}
default: //normal
switch bvalue[i] {
case '\\':
escapeType = 1 //json escapin
case '%':
escapeType = 3 // url escape
default:
buf = append(buf, bvalue[i])
}
}
i++
}
switch escapeType {
case 1:
buf = append(buf, '\\')
case 2:
unicodestr := FastByte2String(bvalue[unicodeidx+1 : i])
if arune, err := strconv.ParseInt(unicodestr, 16, 32); err == nil {
l := len(buf)
buf = append(buf, 0, 0, 0, 0)
runelen := utf8.EncodeRune(buf[l:l+4], rune(arune))
buf = buf[:l+runelen]
} else {
buf = append(buf, bvalue[unicodeidx:i]...)
}
}
return buf
}
func CheckAllStrsIsNotEmpty(strs ...string) bool {
for i := 0; i < len(strs); i++ {
if len(strs[i]) == 0 {
return false
}
}
return true
}
// 解码转义字符,将"\u6821\u56ed\u7f51\t02%20得闲"这类字符串,解码成正常显示的字符串
func ParserJsonEscapeStr(escapedstr string) string {
return FastByte2String(UnEscapeJSONStr([]byte(escapedstr)))
}
func EscapeSQLStr(str string) string {
var buf bytes.Buffer
for _, runedata := range str {
switch runedata {
case '\'':
buf.WriteByte('\'')
buf.WriteByte('\'')
case '\\':
buf.WriteByte('\\')
buf.WriteByte('\\')
default:
buf.WriteRune(runedata)
}
}
return FastByte2String(buf.Bytes())
}
func EscapeStr4Line(str string) string {
var buf bytes.Buffer
for _, runedata := range str {
switch runedata {
case '\r':
buf.WriteByte('\\')
buf.WriteByte('r')
case '\n':
buf.WriteByte('\\')
buf.WriteByte('n')
default:
buf.WriteRune(runedata)
}
}
dataBuf := buf.Bytes()
return *(*string)(unsafe.Pointer(&dataBuf))
}
func UnEscapeStr4Line(str string) string {
var buf bytes.Buffer
var escapeflag int8 = 0
for _, chr := range []byte(str) {
switch escapeflag {
case 1:
escapeflag = 0
switch chr {
case 'r':
buf.WriteByte('\r')
case 'n':
buf.WriteByte('\n')
case 't':
buf.WriteByte('\t')
case 'a':
buf.WriteByte('\a')
case 'b':
buf.WriteByte('\b')
case 'f':
buf.WriteByte('\f')
case 'v':
buf.WriteByte('\v')
case '\\':
buf.WriteByte('\\')
case '"':
buf.WriteByte('"')
case '\'':
buf.WriteByte('\'')
case '/':
buf.WriteByte('/')
default:
buf.WriteByte(chr)
}
default: //normal
switch chr {
case '\\':
escapeflag = 1 //
default:
buf.WriteByte(chr)
}
}
}
dataBuf := buf.Bytes()
return string(dataBuf)
}
func EscapeJsonStrSimple(str string) string {
var buf bytes.Buffer
for _, runedata := range str {
switch runedata {
case '\t':
buf.WriteByte('\\')
buf.WriteByte('t')
case '\f':
buf.WriteByte('\\')
buf.WriteByte('f')
case '\r':
buf.WriteByte('\\')
buf.WriteByte('r')
case '\n':
buf.WriteByte('\\')
buf.WriteByte('n')
case '\\':
buf.WriteByte('\\')
buf.WriteByte('\\')
case '"':
buf.WriteByte('\\')
buf.WriteByte('"')
case '\b':
buf.WriteByte('\\')
buf.WriteByte('b')
default:
buf.WriteRune(runedata)
}
}
return FastByte2String(buf.Bytes())
}
// Copy From DxValue.Record
func EscapeJsonStr(str string) string {
var buf bytes.Buffer
for _, runedata := range str {
switch runedata {
case '\t':
buf.WriteByte('\\')
buf.WriteByte('t')
case '\f':
buf.WriteByte('\\')
buf.WriteByte('f')
case '\r':
buf.WriteByte('\\')
buf.WriteByte('r')
case '\n':
buf.WriteByte('\\')
buf.WriteByte('n')
case '\\':
buf.WriteByte('\\')
buf.WriteByte('\\')
case '"':
buf.WriteByte('\\')
buf.WriteByte('"')
case '\b':
buf.WriteByte('\\')
buf.WriteByte('b')
default:
if runedata < 256 {
buf.WriteByte(byte(runedata))
} else {
buf.Write([]byte{'\\', 'u'})
var b [4]byte
binary.BigEndian.PutUint32(b[:], uint32(runedata))
if b[0] == 0 && b[1] == 0 {
hexstr := Binary2Hex(b[2:])
buf.WriteString(hexstr)
} else {
hexstr := Binary2Hex(b[0:2])
buf.WriteString(hexstr)
buf.Write([]byte{'\\', 'u'})
hexstr = Binary2Hex(b[2:])
buf.WriteString(hexstr)
}
}
}
}
return FastByte2String(buf.Bytes())
}
// 2进制转到16进制
func Binary2Hex(bt []byte) string {
var bf bytes.Buffer
vhex := [16]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}
for _, vb := range bt {
bf.WriteByte(vhex[vb>>4])
bf.WriteByte(vhex[vb&0xF])
}
return FastByte2String(bf.Bytes())
}
func FastByte2String(bt []byte) string {
return *(*string)(unsafe.Pointer(&bt))
}
func BufStart(buf []byte, start, l int) []byte {
return buf[start : start+l]
}
func BufToHexStr(buf []byte, l int, spliterstr string) string {
rval := ""
i := 0
for _, v := range buf {
if (l > 0) && (i >= l) {
break
}
rval = fmt.Sprintf("%s%.2X%s", rval, v, spliterstr)
i++
}
return rval
}
/*
*
RangeStringSplit("a\r\n汉字b\r\n", "\r\n", func)
*/
func RangeStringSplit(s string, sep string, cb func(idx int, s string) bool) int {
if len(sep) == 0 {
cb(0, s)
return 1
}
i := 0
idx := 0
for {
n := strings.Index(s[i:], sep)
if n == -1 {
cb(idx, s[i:])
idx++
break
} else {
ok := cb(idx, s[i:i+n])
idx++
i += n + len(sep)
if !ok || i >= len(s) {
break
}
}
}
return idx
}
/*
**
RangeStringSep("a01;a02", ';', fn); // 2次
RangeStringSep("a01", ';', fn); // 1次
RangeStringSep("a01;", ';', fn); // 1次
RangeStringSep("a01;;", ';', fn); // 2次
*/
func RangeStringSep(s string, sep rune, cb func(idx int, s1 string) bool) int {
s1 := []rune(s)
j := 0
n := 0
i := 0
var ok = true
for ; i < len(s1); i++ {
if s1[i] == sep {
ok = cb(n, string(s1[j:i]))
n++
if !ok {
break
}
j = i + 1
}
}
if ok {
if j < len(s1) {
cb(n, string(s1[j:]))
n++
}
}
return n
}
/*
**
RangeStringSep2("a01;a02", fn, ';', ',');
*/
func RangeStringSep2(s string, cb func(idx int, s1 string) bool, sep0, sep1 rune) int {
s1 := []rune(s)
j := 0
n := 0
i := 0
var ok bool
for ; i < len(s1); i++ {
if s1[i] == sep0 || s1[i] == sep1 {
ok = cb(n, string(s1[j:i]))
n++
if !ok {
break
}
j = i + 1
}
}
if ok {
if j < len(s1) {
cb(n, string(s1[j:]))
n++
}
}
return n
}
func RangeByteFromHexStr(hexstr string, cb func(v byte) bool) int {
hexstr = strings.Replace(hexstr, " ", "", -1)
hexstr = strings.Replace(hexstr, "\r", "", -1)
hexstr = strings.Replace(hexstr, "\n", "", -1)
hexstrArr := []rune(hexstr)
l := len(hexstrArr)
i := 0
for {
if (i + 1) >= l {
break
}
if IsHexChar(hexstrArr[i]) && IsHexChar(hexstrArr[i+1]) {
v := byte(HexValue(hexstrArr[i])<<4 + HexValue(hexstrArr[i+1]))
i += 2
if !cb(v) {
break
}
} else {
break
}
}
return i / 2
}
func HexStrToBuf(hexstr string) []byte {
hexstr = strings.Replace(hexstr, " ", "", -1)
hexstr = strings.Replace(hexstr, "\t", "", -1)
hexstr = strings.Replace(hexstr, "\r", "", -1)
hexstr = strings.Replace(hexstr, "\n", "", -1)
hexstrArr := []rune(hexstr)
l := len(hexstrArr)
l2 := l >> 1
rval := make([]byte, 0, l2)
i := 0
for {
if (i + 1) >= l {
break
}
if IsHexChar(hexstrArr[i]) && IsHexChar(hexstrArr[i+1]) {
v := HexValue(hexstrArr[i])<<4 + HexValue(hexstrArr[i+1])
i += 2
rval = append(rval, byte(v))
} else {
break
}
}
return rval
}
func HexValue(chr rune) int {
c := int(chr)
if (c >= '0') && (c <= '9') {
return c - '0'
} else if c >= 'a' && c <= 'f' {
return 10 + c - 'a'
} else {
return 10 + c - 'A'
}
}
func HexToInt(hex string) int {
r := 0
for _, char := range []rune(hex) {
r = r<<4 + HexValue(char)
}
return r
}
/*
ASCII可显示字符
*/
func IsAsciiPrintByte(c byte) bool {
return (c >= 32 && c <= 126) || // // 32: (Space), 126:~
(c == 10 || c == 13 || c == '\t')
}
func IsAsciiPrintChar(chr rune) bool {
c := byte(chr)
return (c >= 32 && c <= 126) || // // 32: (Space), 126:~
(c == 10 || c == 13 || c == '\t')
}
func IsHexChar(chr rune) bool {
c := byte(chr)
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')
}
func Trim(s string) string {
return strings.Trim(s, " \r\n\t")
}
func CombineIfFirstNotEmpty(s1, s2 string) string {
if len(s1) > 0 {
return s1 + s2
} else {
return s1
}
}
func CombineIfNotEmpty(s1, s2 string) string {
if len(s2) > 0 && len(s1) > 0 {
return s1 + s2
} else {
return ""
}
}
/*
*
CutIfMore(txt, 10, "..."))
*/
func CutIfMore(s string, n int, moreflagstr string) string {
strBuf := []rune(s)
if len(strBuf) < n {
return s
}
s1 := string(strBuf[:n]) + moreflagstr
return s1
}
func LeftStr(s string, n int) string {
strBuf := []rune(s)
if len(strBuf) < n {
n = len(strBuf)
}
s1 := string(strBuf[:n])
return s1
}
func CutLeft(s string, n int) (cut string, remain string) {
strBuf := []rune(s)
if len(strBuf) < n {
n = len(strBuf)
}
cut = string(strBuf[:n])
if len(strBuf) > n {
remain = string(strBuf[n:])
}
return
}
/*
*
The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
*/
func CompareIgnoreCase(s1, s2 string) int {
s1 = strings.ToLower(s1)
s2 = strings.ToLower(s2)
return strings.Compare(s1, s2)
}
/*
**
idx 从0开始
"/", "中国/人民", CutPrefixByRune("/中国/人民", 0, 1, "/")
"/中国/", "人民", CutPrefixByRune("/中国/人民", 1, 1, "/")
*/
func CutPrefixByRune(s string, idx int, cutflag byte, c rune) (cut string, remain string) {
return CutNPrefixFunc(s, idx, cutflag, func(c1 rune) bool {
return c1 == c
})
}
/*
**
idx 从0开始
"/人民", "/中国", CutSuffixByRune("/中国/人民", 0, 1, "/")
"/中国/人民", "", CutSuffixByRune("/中国/人民", 1, 1, "/")
*/
func CutSuffixByRune(s string, idx int, cutflag byte, c rune) (cut string, remain string) {
return CutNSuffixFunc(s, idx, cutflag, func(c1 rune) bool {
return c1 == c
})
}
func CutNPrefixFunc(s string, idx int, cutflag byte, CheckCutBreakFunc func(c rune) bool) (cut string, remain string) {
i := 0
return CutPrefixFunc(s, cutflag, func(c rune) bool {
if CheckCutBreakFunc(c) {
if i == idx {
return true
} else {
i++
return false
}
} else {
return false
}
})
}
func CutNSuffixFunc(s string, idx int, cutflag byte, CheckCutBreakFunc func(c rune) bool) (cut string, remain string) {
i := 0
return CutSuffixFunc(s, cutflag, func(c rune) bool {
if CheckCutBreakFunc(c) {
if i == idx {
return true
} else {
i++
return false
}
} else {
return false
}
})
}
/*
*
如果CheckCutBreakFunc 一直为false, cut则返回"", remain则返回源字符串
返回true表示从该字符进行截断
cutflag 0: "中国/人","民"
cutflag 1: "中国/人民",""
str := "中国/人民";
plug, remain := CutPrefixFunc(str, 0, func(c rune) bool {
if c == '民'{
return true;
}
return false;
})
cutflag 0: "中国","/人民"
cutflag 1: "中国","/人民"
str := "中国/人民";
plug, remain := CutPrefixFunc(str, 0, func(c rune) bool {
if c == '/'{
return true;
}
return false;
})
fmt.Println(CutPrefixFunc("../abc.txt", 1, func(c rune) bool {
if c == '.' || c=='/'{
return false;
}
return true;
}))
../, abc.txt
*/
func CutPrefixFunc(s string, cutflag byte, CheckCutBreakFunc func(c rune) bool) (cut string, remain string) {
strBuf := []rune(s)
n := len(strBuf)
breakn := 0
cutlist := make([]rune, 0, n)
for i := 0; i < n; i++ {
c := strBuf[i]
if CheckCutBreakFunc(c) {
if cutflag == 1 {
cutlist = append(cutlist, c)
breakn = i + 1
} else {
breakn = i
}
break
} else {
cutlist = append(cutlist, c)
}
}
if breakn == 0 {
return "", s
}
return string(cutlist), string(strBuf[breakn:])
}
/*
**
如果CheckCutBreakFunc 一直为false, cut则返回"", remain则返回源字符串
*/
func CutSuffixFunc(s string, cutflag byte, CheckCutBreakFunc func(c rune) bool) (cut string, remain string) {
strBuf := []rune(s)
n := len(strBuf)
breakn := n - 1
for i := n - 1; i >= 0; i-- {
c := strBuf[i]
if CheckCutBreakFunc(c) {
if cutflag == 0 {
breakn = i + 1
} else {
breakn = i
}
break
}
}
if breakn == n-1 {
return "", s
}
return string(strBuf[breakn:]), string(strBuf[:breakn])
}
var num2char string = "0123456789ABCDEF"
func CheckTrimPrefix(s, prefix string) (bool, string) {
if len(prefix) == 0 {
return true, s
}
if !strings.HasPrefix(s, prefix) {
return false, s
}
return true, s[len(prefix):]
}
func CheckTrimSuffix(s, suffix string) (bool, string) {
if len(suffix) == 0 {
return true, s
}
if !strings.HasSuffix(s, suffix) {
return false, s
}
return true, s[:len(s)-len(suffix)]
}
func CheckAddPrefix(s, prefix string) (added bool, rval string) {
if strings.HasPrefix(s, prefix) {
return false, s
}
return true, prefix + s
}
func CheckAddSuffix(s, suffix string) (added bool, rval string) {
if strings.HasSuffix(s, suffix) {
return false, s
}
return true, s + suffix
}
func CheckAddQuoteChr(s string, prefix, suffix rune) string {
runelst := []rune(s)
l := len(runelst)
if l >= 2 && runelst[0] == prefix || runelst[l-1] == suffix {
return s
}
newlst := make([]rune, 0, l+2)
newlst = append(newlst, prefix)
newlst = append(newlst, runelst...)
newlst = append(newlst, suffix)
return string(newlst)
}
func Str2lst(s string, sep string, itmprefix, itmsuffix rune, tolower, emptyignore bool) []string {
if len(s) == 0 {
return nil
}
lst := strings.Split(s, sep)
if itmprefix == 0 && itmsuffix == 0 && !tolower && !emptyignore {
return lst
}
for i := 0; i < len(lst); i++ {
s := Trim(lst[i])
if len(s) == 0 && emptyignore {
continue
}
if tolower {
s = strings.ToLower(s)
}
if itmprefix != 0 && itmsuffix != 0 {
s = CheckAddQuoteChr(s, itmprefix, itmsuffix)
}
lst[i] = s
}
return lst
}
/*
*
截掉前后字符
*/
func CheckTrimQuoteChr(s string, prefix, suffix byte) (bool, string) {
l := len(s)
if l <= 2 || s[0] != prefix || s[l-1] != suffix {
return false, s
}
return true, s[1 : l-1]
}
/*
*
截掉前后字符串
*/
func CheckTrimQuoteString(s string, prefix, suffix string) (bool, string) {
l := len(s)
if l <= len(prefix)+len(suffix) || s[0:len(prefix)] != prefix || s[l-len(suffix):] != suffix {
return false, s
}
return true, s[len(prefix) : l-len(suffix)]
}
func init() {
rand.Seed(time.Now().UnixNano())
}
var (
// 使用下面的r, 并发会有异常
// r *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))
hex_strs = "0123456789ABCDEF"
key_strs = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
pass_0_strs = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
num_strs = "0123456789"
num2_strs = "012356789"
)
// 60个纤程同时进行测试没有异常
func RandHexString(len int) string {
bytes := make([]byte, len)
for i := 0; i < len; i++ {
b := rand.Intn(16)
bytes[i] = byte(hex_strs[b])
}
return string(bytes)
}
func RandFloat64(f float64) float64 {
return f * float64(rand.Intn(100)) / 100.00
}
/*
*
比较耗cpu
*/
func RandBuf(len int) []byte {
bytes := make([]byte, len)
for i := 0; i < len; i++ {
b := rand.Intn(255)
bytes[i] = byte(b)
}
return bytes
}
func RandNumString(len int) string {
bytes := make([]byte, len)
for i := 0; i < len; i++ {
b := rand.Intn(9)
bytes[i] = byte(num_strs[b])
}
return string(bytes)
}
func RandNumStringWithout4(len int) string {
bytes := make([]byte, len)
for i := 0; i < len; i++ {
b := rand.Intn(8)
bytes[i] = byte(num2_strs[b])
}
return string(bytes)
}
func StrNextSerialNo(str string, maxl int, inc int) string {
strn := GetLastNumStr(str, maxl)
if len(strn) == 0 {
return str + fmt.Sprintf("%.2d", inc)
}
strprefix := str[:len(str)-len(strn)]
fmtstr := "%." + fmt.Sprintf("%d", len(strn)) + "d"
nextv, err := strconv.ParseInt(strn, 10, 32)
if err != nil {
nextv = int64(inc)
} else {
nextv += int64(inc)
}
strn = fmt.Sprintf(fmtstr, nextv)
strv := strprefix + strn
return strv
}
func GetLastNumStr(str string, maxl int) string {
rval := ""
j := 0
for i := len(str) - 1; i >= 0; i-- {
if str[i] >= '0' && str[i] <= '9' {
rval = string(str[i]) + rval
j++
if j >= maxl {
break
}
} else {
break
}
}
return rval
}
// 60个纤程同时进行测试没有异常
func RandKeyString(len int) string {
bytes := make([]byte, len)
for i := 0; i < len; i++ {
b := rand.Intn(37 - 1)
bytes[i] = byte(key_strs[b])
}
return string(bytes)
}
func RandPass0String(len int) string {
bytes := make([]byte, len)
for i := 0; i < len; i++ {
b := rand.Intn(62 - 1)
bytes[i] = byte(pass_0_strs[b])
}
return string(bytes)
}
// inttohex
// DecimalToAny(113, 16, 2) = 71
func DecimalToAny(num, n, count int) string {
new_num_str := ""
var remainder int
var remainder_string string
for num != 0 {
remainder = num % n
remainder_string = string(num2char[remainder])
new_num_str = remainder_string + new_num_str //注意顺序
num = num / n
}
length := len(new_num_str)
if length == count {
return new_num_str
}
if length < count { //如果小于8位
for i := 1; i <= count-length; i++ {
new_num_str = "0" + new_num_str
}
return new_num_str
} else {
return "ERROR"
}
}
func AddSuffixForWidth(src string, width int, suffix string) string {
disl := width - len(src)
if disl < 0 {
return src
}
fixl := len(suffix)
if fixl == 0 {
suffix = " "
fixl = 1
}
if fixl == 1 {
rep := bytes.Repeat([]byte(suffix), disl)
str := src + string(rep)
return str
} else {
l := int(math.Ceil(float64(disl) / float64(fixl)))
rep := bytes.Repeat([]byte(suffix), l)
str := src + string(rep[:disl])
return str
}
}
func AddPrefixForWidth(src string, width int, prefix string) string {
disl := width - len(src)
if disl <= 0 {
return src
}
fixl := len(prefix)
if fixl == 0 {
prefix = " "
fixl = 1
}
if fixl == 1 {
rep := bytes.Repeat([]byte(prefix), disl)
str := string(rep) + src
return str
} else {
l := int(math.Ceil(float64(disl) / float64(fixl)))
rep := bytes.Repeat([]byte(prefix), l)
str := string(rep[:disl]) + src
return str
}
}
func Split2StrV1(s string, sep byte) (s1, s2 string) {
if len(s) == 0 {
return
}
idx := bytes.IndexByte([]byte(s), sep)
if idx == -1 {
s1 = s
return
}
s1 = s[:idx]
s2 = s[idx+1:]
return
}
func Split2Str(s, sep string) (s1, s2 string) {
if len(s) == 0 {
return
}
strs := strings.SplitN(s, sep, 2)
s1 = strs[0]
if len(strs) > 1 {
s2 = strs[1]
}
return
}
func Split3Str(s, sep string) (s1, s2, s3 string) {
if len(s) == 0 {
return
}
strs := strings.SplitN(s, sep, 3)
s1 = strs[0]
if len(strs) > 1 {
s2 = strs[1]
}
if len(strs) > 2 {
s3 = strs[2]
}
return
}
func SplitNumericAndRemain(str string) (numstr, remain string) {
if len(str) == 0 {
return
}
dotn := 0
numstr, remain = CutPrefixFunc(str, 0, func(c rune) bool {
if c >= '0' && c <= '9' {
return false
}
if c == '.' {
dotn++
if dotn == 1 {
return false
}
}
return true
})
return
}
func StrToFloat32Def(s string, defval float32) float32 {
v, err := strconv.ParseFloat(s, 32)
if err != nil {
return defval
} else {
return float32(v)
}
}
func StrToFloat64Def(s string, defval float64) float64 {
v, err := strconv.ParseFloat(s, 64)
if err != nil {
return defval
} else {
return float64(v)
}
}
/*
**
1 = "1"
0.1 = "0.1"
*/
func Float64ToStr(val float64) string {
str := strconv.FormatFloat(val, 'f', -1, 64)
return str
}
func Float32ToStr(val float64) string {
str := strconv.FormatFloat(val, 'f', -1, 32)
return str
}
func IsAsciiPrintStr(src string) bool {
strArr := []rune(src)
l := len(strArr)
for i := 0; i < l; i++ {
if !IsAsciiPrintChar(strArr[i]) {
return false
}
}
return true
}
func CheckGetStrlist(strs []string, idx int, def string) string {
if len(strs) > idx {
return strs[idx]
} else {
return def
}
}
func CheckGetValInlst(lst []interface{}, idx int, def interface{}) interface{} {
if len(lst) > idx {
return lst[idx]
} else {
return def
}
}
func IsPrintStr(src string) bool {
strArr := []rune(src)
l := len(strArr)
for i := 0; i < l; i++ {
chr := strArr[i]
if IsAsciiPrintChar(chr) || chr == 10 || strArr[i] == 13 || strArr[i] == '\t' {
continue
} else {
return false
}
}
return true
}
/*
*
0:无BOM
1:UTF8
*/
func DetectBOMType(data []byte) int {
if len(data) >= 3 {
if data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF {
return 1
}
}
return 0
}
/*
*
GB2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;
GBK共收入21886个汉字和图形符号。
GBK: 8140至FEFE
*/
func HaveAnyGBK(data []byte) bool {
length := len(data)
var i int = 0
for i < length {
if data[i] <= 0x7f { // 编码0~127,只有一个字节的编码,兼容ASCII码
i++
continue
} else {
//大于127的使用双字节编码,落在gbk编码范围内的字符
if i+1 < length && (data[i] >= 0x81 && data[i+1] >= 0x40 && data[i] <= 0xfe && data[i+1] <= 0xfe && data[i+1] != 0xf7) {
i += 2
return true
} else { // 非GBK
continue
// return false
}
}
}
return false
}
/*
*
src 长度必须是2的倍数, 必须都是HEX字符, 不能包含空格
*/
func IsHexStr(src string) bool {
strArr := []rune(src)
l := len(strArr)
if l%2 != 0 {
return false
}
for i := 0; i < l; i++ {
if !IsHexChar(strArr[i]) {
return false
}
}
return true
}
func StringsRangeFunc(strs []string, cb func(idx int64, elestr string) bool) (int64, error) {
index := int64(0)
for i := 0; i < len(strs); i++ {
if !cb(int64(i), strs[i]) {
break
}
index++
}
return index, nil
}
/*
**
删除符合条件的元素
*/
func DeleteStrlstEle(strs []string, fn func(s string) bool) []string {
for i := len(strs) - 1; i >= 0; i-- {
if fn(strs[i]) {
strs = append(strs[:i], strs[i+1:]...)
}
}
return strs
}
func StrIndex(s string, strlst ...string) int {
for i := 0; i < len(strlst); i++ {
if s == strlst[i] {
return i
}
}
return -1
}
func StrIndexIgnoreCase(s string, strlst ...string) int {
for i := 0; i < len(strlst); i++ {
if strings.ToLower(s) == strings.ToLower(strlst[i]) {
return i
}
}
return -1
}
/*
*
1个月 1, 个月
1 天 1,天
*/
func SplitQuantifiersUnits(s string) (qua string, unit string) {
runelst := []rune(Trim(s))
for i := 0; i < len(runelst); i++ {
chr := runelst[i]
if chr >= '0' && chr <= '9' {
continue
} else if chr == '-' || chr == '+' {
continue
} else if chr == '.' {
continue
}
if chr == ' ' || chr == '\t' || chr == '\n' {
qua = string(runelst[:i])
unit = string(runelst[i+1:])
break
} else {
qua = string(runelst[:i])
unit = string(runelst[i:])
break
}
}
return
}
func StrTo3Float64(str string, sep string) (f1, f2, f3 float64) {
strs := strings.SplitN(str, sep, 4)
if len(strs) >= 1 {
f1 = StrToFloat64Def(Trim(strs[0]), 0)
if len(strs) >= 2 {
f2 = StrToFloat64Def(Trim(strs[1]), 0)
if len(strs) >= 3 {
f3 = StrToFloat64Def(Trim(strs[2]), 0)
}
}
}
return
}
func StrToInts(str string, sep string) (rval []int) {
strs := strings.Split(str, sep)
rval = make([]int, 0, len(strs))
for i := 0; i < len(strs); i++ {
s := Trim(strs[i])
if len(s) > 0 {
v, err := strconv.ParseInt(s, 10, 64)
if err == nil {
rval = append(rval, int(v))
}
}
}
return
}
func StrToUInt8List(str string, sep string) (rval []byte) {
strs := strings.Split(str, sep)
rval = make([]byte, 0, len(strs))
for i := 0; i < len(strs); i++ {
s := Trim(strs[i])
if len(s) > 0 {
v, err := strconv.ParseInt(s, 10, 64)
if err == nil {
rval = append(rval, byte(v))
}
}
}
return
}
func Int8ListToStrs(lst []int8, sep string) string {
var bb strings.Builder
for i := 0; i < len(lst); i++ {
if bb.Len() > 0 {
bb.WriteString(sep)
}
bb.WriteString(fmt.Sprintf("%d", lst[i]))
}
return bb.String()
}
func StrToInt8List(str string, sep string) (rval []int8) {
strs := strings.Split(str, sep)
rval = make([]int8, 0, len(strs))
for i := 0; i < len(strs); i++ {
s := Trim(strs[i])
if len(s) > 0 {
v, err := strconv.ParseInt(s, 10, 64)
if err == nil {
rval = append(rval, int8(v))
}
}
}
return
}
func UInt8ListToStrs(lst []byte, sep string) string {
var bb strings.Builder
for i := 0; i < len(lst); i++ {
if bb.Len() > 0 {
bb.WriteString(sep)
}
bb.WriteString(fmt.Sprintf("%d", lst[i]))
}
return bb.String()
}
func StrToIntDef(s string, defval int) int {
v, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return defval
} else {
return int(v)
}
}
func StrToInt8Def(s string, defval int8) int8 {
return int8(StrToInt64Def(s, int64(defval)))
}
func StrToInt64Def(s string, defval int64) int64 {
v, err := strconv.ParseInt(s, 10, 64)
if err != nil {
if strings.HasPrefix(s, "0x") {
v, err := strconv.ParseInt(s[2:], 16, 64)
if err != nil {
return defval
} else {
return v
}
}
return defval
} else {
return int64(v)
}
}
func ReplaceReg(s string, regP string, new string) (string, error) {
reg, err := regexp.Compile(regP)
if err != nil {
return "", err
}
return string(reg.ReplaceAll([]byte(s), []byte(new))), nil
}
/*
*
s := "a b c d " -> "a b c d "
*/
func ReplaceMultiSpace2One(s string, new string) string {
str, err := ReplaceReg(s, "( )+", new)
if err != nil {
return s
}
return str
}
/*
*
ReplaceMultiAny2One("a b c d ", " ", ":"); -> "a:b:c:d:"
ReplaceMultiAny2One("a b c d "," "," ")->"a b c d "
ReplaceMultiAny2One("ababaaa aab ac d aaa ","ab","x")->"xaaa ax ac d aaa "
ReplaceMultiAny2One("aaaaa aab ac d aaa ", "aa", "x")->"xa xb ac d xa"
*/
func ReplaceMultiAny2One(s string, any, new string) string {
regP := fmt.Sprintf("(%s)+", regexp.QuoteMeta(any))
//fmt.Println(regP)
str, err := ReplaceReg(s, regP, new)
if err != nil {
return s
}
return str
}
/*
*
忽略大小写
`<td>a</td><td>b</td>`
ReplaceArea(str, "<td>", "</td>", "<td>abc</td>") = <td>abc</td><td>abc</td>
*/
func ReplaceArea(s string, start, end string, new string) string {
// regexp.MustCompile(`(?i:^hello).*Go`)
strRegFind := fmt.Sprintf("(?i:%s)[\\s\\S]*?(?i:%s)",
regexp.QuoteMeta(start), regexp.QuoteMeta(end))
reg, err := regexp.Compile(strRegFind)
if err != nil {
return s
}
return string(reg.ReplaceAll([]byte(s), []byte(new)))
}
/*
*
忽略大小写
*/
func ReplaceAll(s string, old, new string) string {
strRegFind := fmt.Sprintf("(?i)%s", regexp.QuoteMeta(old))
reg, err := regexp.Compile(strRegFind)
if err != nil {
return s
}
return string(reg.ReplaceAll([]byte(s), []byte(new)))
}
/*
*
不支持....
*/
func GetAreaBK(s string, start, end string, idx int) string {
// (?<=<td>).*?(?=</td>) // 不支持
strRegFind := fmt.Sprintf("(?<=%s).*?(?=%s)",
regexp.QuoteMeta(start), regexp.QuoteMeta(end))
reg, err := regexp.Compile(strRegFind)
if err != nil {
return s
}
return reg.FindString(s)
}
/*
*
查找s2中不存在与s1中的元素
FindNonElement("1,2,3", "3,4,2,5") = "4,5"
*/
func FindNonElement(s1, s2 string, sep rune) string {
rval := make([]rune, 0, len(s1))
RangeStringSep(s2, sep, func(idx int, s string) bool {
if !ContainElement(s1, s, sep) {
if len(rval) > 0 {
rval = append(rval, sep)
}
rval = append(rval, []rune(s)...)
}
return true
})
return string(rval)
}
/*
*
false = ContainElement("1,2,3,16", ",", "6")
*/
func ContainElement(s string, ele string, sep rune) (rval bool) {
RangeStringSep(s, sep, func(idx int, s1 string) bool {
rval = s1 == ele
return !rval
})
return
}
/*
`<td>a</td><td>b</td>`
GetBetween(str, "<td>", "</td>") = a
GetBetween("$now$", "$", "$") = "now"
*/
func GetBetweenEx(str string, start, end string, idx int) (ok bool, val string) {
j := 0
for {
n := strings.Index(str, start)
if n == -1 {
return false, ""
}
str = string([]byte(str)[n+len(start):])
m := strings.Index(str, end)
if m == -1 {
return false, ""
}
if j == idx {
str = string([]byte(str)[:m])
return true, str
} else {
str = string([]byte(str)[m+len(end):])
if len(str) <= len(start) {
return false, ""
}
}
j++
}
}
/*
`<td>a</td><td>b</td>`
GetBetween(str, "<td>", "</td>") = a
GetBetween("$now$", "$", "$") = "now"
*/
func GetBetween(str string, start, end string, idx int) string {
j := 0
for {
n := strings.Index(str, start)
if n == -1 {
return ""
}
str = string([]byte(str)[n+len(start):])
m := strings.Index(str, end)
if m == -1 {
return ""
}
if j == idx {
str = string([]byte(str)[:m])
return str
} else {
str = string([]byte(str)[m+len(end):])
if len(str) <= len(start) {
return ""
}
}
j++
}
}
func IsWindows() bool {
return runtime.GOOS == "windows"
}
func IsLinux() bool {
return runtime.GOOS == "linux"
}
type encoding int
const (
encodePath encoding = 1 + iota
encodePathSegment
encodeHost
encodeZone
encodeUserPassword
encodeQueryComponent
encodeFragment
)
type EscapeError string
func (e EscapeError) Error() string {
return "invalid URL escape " + strconv.Quote(string(e))
}
type InvalidHostError string
func (e InvalidHostError) Error() string {
return "invalid character " + strconv.Quote(string(e)) + " in host name"
}
const upperhex = "0123456789ABCDEF"
func ishex(c byte) bool {
switch {
case '0' <= c && c <= '9':
return true
case 'a' <= c && c <= 'f':
return true
case 'A' <= c && c <= 'F':
return true
}
return false
}
func unhex(c byte) byte {
switch {
case '0' <= c && c <= '9':
return c - '0'
case 'a' <= c && c <= 'f':
return c - 'a' + 10
case 'A' <= c && c <= 'F':
return c - 'A' + 10
}
return 0
}
// Return true if the specified character should be escaped when
// appearing in a URL string, according to RFC 3986.
//
// Please be informed that for now shouldEscape does not check all
// reserved characters correctly. See golang.org/issue/5684.
func shouldEscape(c byte, mode encoding) bool {
// §2.3 Unreserved characters (alphanum)
if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
return false
}
if mode == encodeHost || mode == encodeZone {
// §3.2.2 Host allows
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
// as part of reg-name.
// We add : because we include :port as part of host.
// We add [ ] because we include [ipv6]:port as part of host.
// We add < > because they're the only characters left that
// we could possibly allow, and Parse will reject them if we
// escape them (because hosts can't use %-encoding for
// ASCII bytes).
switch c {
case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '[', ']', '<', '>', '"':
return false
}
}
switch c {
case '-', '_', '.', '~': // §2.3 Unreserved characters (mark)
return false
case '$', '&', '+', ',', '/', ':', ';', '=', '?', '@': // §2.2 Reserved characters (reserved)
// Different sections of the URL allow a few of
// the reserved characters to appear unescaped.
switch mode {
case encodePath: // §3.3
// The RFC allows : @ & = + $ but saves / ; , for assigning
// meaning to individual path segments. This package
// only manipulates the path as a whole, so we allow those
// last three as well. That leaves only ? to escape.
return c == '?'
case encodePathSegment: // §3.3
// The RFC allows : @ & = + $ but saves / ; , for assigning
// meaning to individual path segments.
return c == '/' || c == ';' || c == ',' || c == '?'
case encodeUserPassword: // §3.2.1
// The RFC allows ';', ':', '&', '=', '+', '$', and ',' in
// userinfo, so we must escape only '@', '/', and '?'.
// The parsing of userinfo treats ':' as special so we must escape
// that too.
return c == '@' || c == '/' || c == '?' || c == ':'
case encodeQueryComponent: // §3.4
// The RFC reserves (so we must escape) everything.
return true
case encodeFragment: // §4.1
// The RFC text is silent but the grammar allows
// everything, so escape nothing.
return false
}
}
if mode == encodeFragment {
// RFC 3986 §2.2 allows not escaping sub-delims. A subset of sub-delims are
// included in reserved from RFC 2396 §2.2. The remaining sub-delims do not
// need to be escaped. To minimize potential breakage, we apply two restrictions:
// (1) we always escape sub-delims outside of the fragment, and (2) we always
// escape single quote to avoid breaking callers that had previously assumed that
// single quotes would be escaped. See issue #19917.
switch c {
case '!', '(', ')', '*':
return false
}
}
// Everything else must be escaped.
return true
}
// QueryUnescape does the inverse transformation of QueryEscape,
// converting each 3-byte encoded substring of the form "%AB" into the
// hex-decoded byte 0xAB.
// It returns an error if any % is not followed by two hexadecimal
// digits.
func QueryUnescape(s string) (string, error) {
return unescape(s, encodeQueryComponent)
}
// PathUnescape does the inverse transformation of PathEscape,
// converting each 3-byte encoded substring of the form "%AB" into the
// hex-decoded byte 0xAB. It returns an error if any % is not followed
// by two hexadecimal digits.
//
// PathUnescape is identical to QueryUnescape except that it does not
// unescape '+' to ' ' (space).
func PathUnescape(s string) (string, error) {
return unescape(s, encodePathSegment)
}
// unescape unescapes a string; the mode specifies
// which section of the URL string is being unescaped.
func unescape(s string, mode encoding) (string, error) {
// Count %, check that they're well-formed.
n := 0
hasPlus := false
for i := 0; i < len(s); {
switch s[i] {
case '%':
n++
if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
s = s[i:]
if len(s) > 3 {
s = s[:3]
}
return "", EscapeError(s)
}
// Per https://tools.ietf.org/html/rfc3986#page-21
// in the host component %-encoding can only be used
// for non-ASCII bytes.
// But https://tools.ietf.org/html/rfc6874#section-2
// introduces %25 being allowed to escape a percent sign
// in IPv6 scoped-address literals. Yay.
if mode == encodeHost && unhex(s[i+1]) < 8 && s[i:i+3] != "%25" {
return "", EscapeError(s[i : i+3])
}
if mode == encodeZone {
// RFC 6874 says basically "anything goes" for zone identifiers
// and that even non-ASCII can be redundantly escaped,
// but it seems prudent to restrict %-escaped bytes here to those
// that are valid host name bytes in their unescaped form.
// That is, you can use escaping in the zone identifier but not
// to introduce bytes you couldn't just write directly.
// But Windows puts spaces here! Yay.
v := unhex(s[i+1])<<4 | unhex(s[i+2])
if s[i:i+3] != "%25" && v != ' ' && shouldEscape(v, encodeHost) {
return "", EscapeError(s[i : i+3])
}
}
i += 3
case '+':
hasPlus = mode == encodeQueryComponent
i++
default:
if (mode == encodeHost || mode == encodeZone) && s[i] < 0x80 && shouldEscape(s[i], mode) {
return "", InvalidHostError(s[i : i+1])
}
i++
}
}
if n == 0 && !hasPlus {
return s, nil
}
var t strings.Builder
t.Grow(len(s) - 2*n)
for i := 0; i < len(s); i++ {
switch s[i] {
case '%':
t.WriteByte(unhex(s[i+1])<<4 | unhex(s[i+2]))
i += 2
case '+':
if mode == encodeQueryComponent {
t.WriteByte(' ')
} else {
t.WriteByte('+')
}
default:
t.WriteByte(s[i])
}
}
return t.String(), nil
}
// QueryEscape escapes the string so it can be safely placed
// inside a URL query.
func QueryEscape(s string) string {
return escape(s, encodeQueryComponent)
}
// PathEscape escapes the string so it can be safely placed inside a URL path segment,
// replacing special characters (including /) with %XX sequences as needed.
func PathEscape(s string) string {
return escape(s, encodePathSegment)
}
func escape(s string, mode encoding) string {
spaceCount, hexCount := 0, 0
for i := 0; i < len(s); i++ {
c := s[i]
if shouldEscape(c, mode) {
if c == ' ' && mode == encodeQueryComponent {
spaceCount++
} else {
hexCount++
}
}
}
if spaceCount == 0 && hexCount == 0 {
return s
}
var buf [64]byte
var t []byte
required := len(s) + 2*hexCount
if required <= len(buf) {
t = buf[:required]
} else {
t = make([]byte, required)
}
if hexCount == 0 {
copy(t, s)
for i := 0; i < len(s); i++ {
if s[i] == ' ' {
t[i] = '+'
}
}
return string(t)
}
j := 0
for i := 0; i < len(s); i++ {
switch c := s[i]; {
case c == ' ' && mode == encodeQueryComponent:
t[j] = '+'
j++
case shouldEscape(c, mode):
t[j] = '%'
t[j+1] = upperhex[c>>4]
t[j+2] = upperhex[c&15]
j += 3
default:
t[j] = s[i]
j++
}
}
return string(t)
}
type StrMap map[string]string
func NewStrMap() StrMap {
return make(StrMap)
}
func NewStrMapFromURLStr(s string) StrMap {
strmap := NewStrMap()
strmap.URLFormDecode(s)
return strmap
}
func NewStrMapEx(s, kvsep, itmsep string) StrMap {
r := make(StrMap)
r.ParseKVPairs(s, kvsep, itmsep)
return r
}
func (this StrMap) Reset() {
for k := range this {
delete(this, k)
}
}
// ExecReplace 利用映射关系进行替换, key -> value
func (this StrMap) ExecReplace(s string) string {
for k, v := range this {
s = ReplaceAll(s, k, v)
}
return s
}
func (this StrMap) SortRange(fn func(k, v string) bool) {
if this == nil {
return
}
keys := make([]string, 0, len(this))
for k := range this {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := this[k]
if !fn(k, v) {
break
}
}
}
func (this StrMap) SortRangeEncode(kvspliter string, itmspliter string, fn func(k, v string) bool) string {
if this == nil {
return ""
}
var buf strings.Builder
this.SortRange(func(k, v string) bool {
if fn(k, v) {
if buf.Len() > 0 {
buf.WriteString(itmspliter)
}
buf.WriteString(k)
buf.WriteString(kvspliter)
buf.WriteString(v)
}
return true
})
return buf.String()
}
func (this StrMap) Encode(kvspliter string, itmspliter string) string {
if this == nil {
return ""
}
var buf strings.Builder
keys := make([]string, 0, len(this))
for k := range this {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
if buf.Len() > 0 {
buf.WriteString(itmspliter)
}
v := this[k]
buf.WriteString(k)
buf.WriteString(kvspliter)
buf.WriteString(v)
}
return buf.String()
}
func MapEncode(strMap map[string]string, kvsep, itmsep string, escapeflag bool, bb io.Writer) {
keys := make([]string, 0, len(strMap))
for k := range strMap {
keys = append(keys, k)
}
sort.Strings(keys)
i := 0
for _, k := range keys {
v := strMap[k]
if i > 0 {
bb.Write([]byte(itmsep))
}
if escapeflag {
keyEscaped := QueryEscape(k)
bb.Write([]byte(keyEscaped))
bb.Write([]byte(kvsep))
bb.Write([]byte(QueryEscape(v)))
} else {
bb.Write([]byte(k))
bb.Write([]byte(kvsep))
bb.Write([]byte(v))
}
i++
}
}
func (this StrMap) DeleteByKeylst(keylst ...string) (r int) {
for _, k := range keylst {
delete(this, k)
r++
}
return
}
func (this StrMap) URLFormEncodeKeylst(keylst ...string) string {
var sb strings.Builder
for _, k := range keylst {
if v, ok := this[k]; ok {
if sb.Len() > 0 {
sb.WriteByte('&')
}
keyEscaped := QueryEscape(k)
sb.WriteString(keyEscaped)
sb.WriteByte('=')
sb.WriteString(QueryEscape(v))
}
}
return sb.String()
}
func (this StrMap) URLFormEncode() string {
if this == nil {
return ""
}
var buf strings.Builder
keys := make([]string, 0, len(this))
for k := range this {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := this[k]
keyEscaped := QueryEscape(k)
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(keyEscaped)
buf.WriteByte('=')
buf.WriteString(QueryEscape(v))
}
return buf.String()
}
func (this StrMap) URLFormDecode(s string) {
lst := strings.Split(s, "&")
if len(lst) == 0 {
return
}
for i := 0; i < len(lst); i++ {
k, v := Split2Str(lst[i], "=")
k, _ = QueryUnescape(k)
v, _ = QueryUnescape(v)
if len(k) > 0 {
this[k] = v
}
}
}
func (this StrMap) CopyFrom(src StrMap) {
for k, v := range src {
this[k] = v
}
}
func (this StrMap) ParseKVPairsEx(s string, kvsep string, itmsep string, keylower bool) {
lst := strings.Split(s, itmsep)
if len(lst) == 0 {
return
}
for i := 0; i < len(lst); i++ {
k, v := Split2Str(lst[i], kvsep)
if len(k) > 0 {
if keylower {
k = strings.ToLower(k)
}
this[k] = v
}
}
}
func (this StrMap) ParseKVPairs(s string, kvsep string, itmsep string) {
lst := strings.Split(s, itmsep)
if len(lst) == 0 {
return
}
for i := 0; i < len(lst); i++ {
k, v := Split2Str(lst[i], kvsep)
k = Trim(k)
if len(k) > 0 {
this[k] = v
}
}
}
func (this StrMap) StringByName(k string, def string) string {
if v, ok := this[k]; ok {
return v
} else {
return def
}
}
func (this StrMap) IntByName(k string, def int) int {
if v, ok := this[k]; ok {
if len(v) == 0 {
return def
}
return StrToIntDef(v, def)
} else {
return def
}
}
func (this StrMap) Float64ByName(k string, def float64) float64 {
if v, ok := this[k]; ok {
return StrToFloat64Def(v, def)
} else {
return def
}
}
func (this StrMap) U8ByName(k string, def byte) byte {
return byte(this.IntByName(k, int(def)))
}
func (this StrMap) Int8ByName(k string, def int8) int8 {
return int8(this.IntByName(k, int(def)))
}
func (this StrMap) Int16ByName(k string, def int16) int16 {
return int16(this.IntByName(k, int(def)))
}
func (this StrMap) UnixTimeByName(k string, def time.Time) time.Time {
v := this.IntByName(k, -99999)
if v == -99999 {
return def
} else {
return time.Unix(int64(v), 0)
}
}
/*
解析命令行
XX.exe -a=v
*/
func (this StrMap) ParseCmdArgs(args []string) {
for i := 0; i < len(args); i++ {
s1, s2 := Split2Str(args[i], "=")
if len(s1) > 0 {
if s1[0] == '-' {
s1 = s1[1:]
}
if len(s2) == 0 {
s2 = s1
if i == 0 {
this["0"] = s1
} else {
this[s1] = s2
}
} else {
_, s2 = CheckTrimQuoteChr(s2, QUOTECHR, QUOTECHR)
this[s1] = s2
}
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ymofen/gobase.git
git@gitee.com:ymofen/gobase.git
ymofen
gobase
gobase
v1.2.24053

搜索帮助

344bd9b3 5694891 D2dac590 5694891