Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: strings and bytes: add CutSpace function #63194

Open
cblach opened this issue Sep 24, 2023 · 3 comments · May be fixed by #63195
Open

proposal: strings and bytes: add CutSpace function #63194

cblach opened this issue Sep 24, 2023 · 3 comments · May be fixed by #63195
Labels
Milestone

Comments

@cblach
Copy link

cblach commented Sep 24, 2023

Golang's cut function is very useful for reducing boilerplate, when parsing text/byte segment. Likewise the bytes.Fields and strings.Fields is useful for parsing spacing separated data fields.

However, sometimes when parsing text it's useful to Cut using white spaces as seperator and considering the the whole whitespace segment as a single seperator (like Fields does). For instance when scanning and parsing a config file that should allow any whitespace as key-value separator, this allows separation of the key and value with less boilerplate:

package main
import(
    "bufio"
    "fmt"
    "strings"
    "unicode"
)

func main() {
    config := "key\tthis is the key value\n" +
        "otherkey another key value\n" +
        "keywithnovalue"
    scanner := bufio.NewScanner(strings.NewReader(config))

    for scanner.Scan() {
        key, value, found := strings.CutSpace(scanner.Text())
        fmt.Println("key:", key)
        if found {
            fmt.Println("value:", value)
        }
    }
}

I propose adding strings.CutSpace and bytes.CutSpace which slices around the each instance of one or more consecutive white space characters, as defined by unicode.IsSpace, returning the text before and after the white space characters.

strings.CutSpace:

// CutSpace slices s around the each instance of one or more consecutive white space
// characters, as defined by unicode.IsSpace, returning the text before and after the
// white space characters. The found result reports white space characters appears in s.
// If no whitespace characters appear in s, CutSpace returns s, "", false.
func CutSpace(s string) (before, after string, found bool) {
	i := indexFunc(s, unicode.IsSpace, true)
	if i == -1 {
		return s, "", false
	}
	return s[:i], TrimLeftFunc(s[i:], unicode.IsSpace), true
}

bytes.CutSpace

// CutSpace slices s around the each instance of one or more consecutive white space
// characters, as defined by unicode.IsSpace, returning the text before and after the
// white space characters. The found result reports white space characters appears in s.
// If no whitespace characters appear in s, CutSpace returns s, nil, false.
//
// CutSpace returns slices of the original slice s, not copies.
func CutSpace(s []byte) (before, after []byte, found bool) {
	i := indexFunc(s, unicode.IsSpace, true)
	if i == -1 {
		return s, nil, false
	}
	return s[:i], TrimLeftFunc(s[i:], unicode.IsSpace), true
}
@gopherbot gopherbot added this to the Proposal milestone Sep 24, 2023
@cblach cblach linked a pull request Sep 24, 2023 that will close this issue
@seankhliao
Copy link
Member

how common is this?
#46336 had a lot of justification for just strings.Cut and nothing else.

@gopherbot
Copy link

Change https://go.dev/cl/530835 mentions this issue: strings: added CutSpace, bytes: added CutSpace

@ianlancetaylor
Copy link
Contributor

Do you know whether there is code in the Go standard library that would benefit from this? One of the strongest arguments for adding strings.Cut was the number of places that it could be used in the standard library (see #46336).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Incoming
Development

Successfully merging a pull request may close this issue.

4 participants