From bfa97bc81a7188eb09e71f450ce863830c8a87fe Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Thu, 23 Jan 2025 14:58:51 +0800 Subject: [PATCH] fix: find words with specified sep and quote --- utils/tags.go | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/utils/tags.go b/utils/tags.go index 9926630..6bd4bef 100644 --- a/utils/tags.go +++ b/utils/tags.go @@ -39,28 +39,32 @@ func Unquote(str string) string { } func findString(str []byte, offset int) (string, int) { - return _findWord(str, offset, "\n\r") + return _findWord(str, offset, "\n\r", isQuoteCharInternal) } func findWord(str []byte, offset int) (string, int) { - return _findWord(str, offset, " :,\t\n}]") + return _findWord(str, offset, " :,\t\n}]", isQuoteCharInternal) } -func _findWord(str []byte, offset int, sepChars string) (string, int) { +func isQuoteCharInternal(ch byte) (bool, string) { + switch ch { + case '"': + return true, "\"" + case '\'': + return true, "'" + default: + return false, "" + } +} + +func _findWord(str []byte, offset int, sepChars string, isQuoteChar func(ch byte) (bool, string)) (string, int) { var buffer bytes.Buffer i := skipEmpty(str, offset) if i >= len(str) { return "", i } - var endstr string - quote := false - if str[i] == '"' { - quote = true - endstr = "\"" - i++ - } else if str[i] == '\'' { - quote = true - endstr = "'" + quote, endstr := isQuoteChar(str[i]) + if quote { i++ } else { // endstr = " :,\t\n\r}]" @@ -98,22 +102,30 @@ func _findWord(str []byte, offset int, sepChars string) (string, int) { } func FindWords(str []byte, offset int) []string { + words, err := FindWords2(str, offset, " :,\t\n}]", isQuoteCharInternal) + if err != nil { + panic(err.Error()) + } + return words +} + +func FindWords2(str []byte, offset int, sepChars string, isQuoteChar func(ch byte) (bool, string)) ([]string, error) { words := make([]string, 0) for offset < len(str) { - word, i := findWord(str, offset) + word, i := _findWord(str, offset, sepChars, isQuoteChar) words = append(words, word) i = skipEmpty(str, i) if i < len(str) { - if str[i] == ',' { + if strings.IndexByte(sepChars, str[i]) >= 0 { offset = i + 1 } else { - panic(fmt.Sprintf("Malformed multi value string: %s", string(str[offset:]))) + return nil, fmt.Errorf("Malformed multi value string: %s", string(str[offset:])) } } else { offset = i } } - return words + return words, nil } func TagMap(tag reflect.StructTag) map[string]string { @@ -155,7 +167,7 @@ func SplitCSV(csv string) []string { str := []byte(csv) for offset < len(str) { var word string - word, offset = _findWord(str, offset, ",\r\n") + word, offset = _findWord(str, offset, ",\r\n", isQuoteCharInternal) words = append(words, word) if offset < len(str) { offset++