Skip to content

Commit

Permalink
[strutil] Add support of escaped strings to 'Fields'
Browse files Browse the repository at this point in the history
  • Loading branch information
andyone committed Nov 15, 2024
1 parent 78fe48e commit 5da93de
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* `[req]` Added `Retrier`
* `[req]` Make `Limiter` public
* `[log]` Added `WithFullCallerPath` option to enable the output of the full caller path
* `[strutil]` Added support of escaped strings to `Fields`

### [13.11.0](https://kaos.sh/ek/13.11.0)

Expand Down
4 changes: 2 additions & 2 deletions strutil/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ func ExampleReplaceIgnoreCase() {
}

func ExampleFields() {
fmt.Printf("%#v\n", Fields("Bob Alice, 'Mary Key', \"John Dow\""))
fmt.Printf("%#v\n", Fields(`Bob Alice, 'Mary Key', "John \"Big John\" Dow"`))

// Output:
// []string{"Bob", "Alice", "Mary Key", "John Dow"}
// []string{"Bob", "Alice", "Mary Key", "John \"Big John\" Dow"}
}

func ExampleReadField() {
Expand Down
34 changes: 22 additions & 12 deletions strutil/strutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,37 +365,47 @@ MAINLOOP:
// consecutive white space or comma characters
func Fields(data string) []string {
var result []string
var item strings.Builder
var buf bytes.Buffer
var waitChar rune
var escaped bool

for _, char := range data {
switch char {
case '\\':
buf.WriteRune(char)
escaped = true
case '"', '\'', '`', '“', '”', '‘', '’', '«', '»', '„':
if waitChar == 0 {
if waitChar == 0 && !escaped {
waitChar = getClosingChar(char)
} else if waitChar != 0 && waitChar == char {
result = appendField(result, item.String())
item.Reset()
} else if waitChar != 0 && waitChar == char && !escaped {
result = appendField(result, buf.String())
buf.Reset()
waitChar = 0
} else {
item.WriteRune(char)
if escaped {
buf.Truncate(buf.Len() - 1)
}
buf.WriteRune(char)
escaped = false
}

case ',', ';', ' ':
if waitChar != 0 {
item.WriteRune(char)
buf.WriteRune(char)
escaped = false
} else {
result = appendField(result, item.String())
item.Reset()
result = appendField(result, buf.String())
buf.Reset()
}

default:
item.WriteRune(char)
buf.WriteRune(char)
escaped = false
}
}

if item.Len() != 0 {
result = appendField(result, item.String())
if buf.Len() != 0 {
result = appendField(result, buf.String())
}

return result
Expand Down
6 changes: 3 additions & 3 deletions strutil/strutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,13 @@ func (s *StrUtilSuite) TestFields(c *C) {
c.Assert(Fields("1,2,3,4,5"), DeepEquals, []string{"1", "2", "3", "4", "5"})
c.Assert(Fields("1;2;3;4;5"), DeepEquals, []string{"1", "2", "3", "4", "5"})
c.Assert(Fields("1, 2, 3, 4, 5"), DeepEquals, []string{"1", "2", "3", "4", "5"})
c.Assert(Fields("\"1 2\" 3 \"4 5\""), DeepEquals, []string{"1 2", "3", "4 5"})
c.Assert(Fields(`"1 2" 3 "4 5"`), DeepEquals, []string{"1 2", "3", "4 5"})
c.Assert(Fields("'1 2' 3 '4 5'"), DeepEquals, []string{"1 2", "3", "4 5"})
c.Assert(Fields("‘1 2’ 3 ‘4 5’"), DeepEquals, []string{"1 2", "3", "4 5"})
c.Assert(Fields("“1 2” 3 “4 5”"), DeepEquals, []string{"1 2", "3", "4 5"})
c.Assert(Fields("„1 2“ 3 «4 5»"), DeepEquals, []string{"1 2", "3", "4 5"})
c.Assert(Fields("«1 '2'» 3 «4 “5”»"), DeepEquals, []string{"1 '2'", "3", "4 “5”"})
c.Assert(Fields("Bob Alice, 'Mary Key', \"John 'Dow'\""), DeepEquals, []string{"Bob", "Alice", "Mary Key", "John 'Dow'"})
c.Assert(Fields(`Bob Alice, 'Mary Key', "John \"Big John\" 'Dow'"`), DeepEquals, []string{"Bob", "Alice", "Mary Key", "John \"Big John\" 'Dow'"})
}

func (s *StrUtilSuite) TestReadField(c *C) {
Expand Down Expand Up @@ -260,7 +260,7 @@ func (s *StrUtilSuite) BenchmarkSize(c *C) {

func (s *StrUtilSuite) BenchmarkFields(c *C) {
for i := 0; i < c.N; i++ {
Fields("\"1 2\" 3 \"4 5\"")
Fields(`"123" 59 "31" '2'`)
}
}

Expand Down

0 comments on commit 5da93de

Please sign in to comment.