strings

package
v0.2.14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 6, 2026 License: MIT Imports: 4 Imported by: 0

README

strings

import "github.com/gechr/x/strings"

Package strings provides string helpers: split, contains, indent/dedent, truncate, and blank checks.

Index

func AppendCSV

func AppendCSV(dst []string, raw string) []string

AppendCSV splits raw on commas, trims whitespace, drops empty values, and appends the remaining values to dst.

Example
fmt.Printf("%q\n", xstrings.AppendCSV([]string{"x"}, " a, b ,, c "))

Output:

["x" "a" "b" "c"]

func Closest

func Closest(target string, candidates []string) string

Closest returns the candidate nearest to target, suitable for a "did you mean?" suggestion. Distance is the Damerau-Levenshtein (optimal string alignment) edit distance, so an adjacent transposition like "verfiy" counts as one edit, not two - the common typo plain Levenshtein over-penalizes. It returns "" when the nearest candidate is further than a third of target's length in edits, so an unrelated word is never suggested. An empty target carries no signal and suggests nothing. Ties resolve to the first candidate.

Closest("verfiy", []string{"verify", "deep"}) // "verify"
Closest("xyzzy", []string{"verify", "deep"})  // ""
Example
fmt.Printf("%q\n", xstrings.Closest("verfiy", []string{"verify", "deep"}))
fmt.Printf("%q\n", xstrings.Closest("xyzzy", []string{"verify", "deep"}))

Output:

"verify"
""

func CompactLines

func CompactLines(s, sep string) string

CompactLines trims lines, drops blank lines, removes duplicate lines while preserving first-seen order, and joins the remaining lines with sep.

Example
fmt.Println(xstrings.CompactLines("  foo \n\nbar\nfoo\n", ", "))

Output:

foo, bar

func CompareFold

func CompareFold(a, b string) int

CompareFold compares a and b case-insensitively, using the same simple case-folding as strings.EqualFold, and returns -1, 0, or 1 following the cmp.Compare convention. CompareFold(a, b) == 0 iff strings.EqualFold(a, b).

Example
fmt.Println(xstrings.CompareFold("Go", "go"))
fmt.Println(xstrings.CompareFold("abc", "ABD"))
fmt.Println(xstrings.CompareFold("B", "a"))

Output:

0
-1
1

func CompareNatural

func CompareNatural(a, b string) int

CompareNatural orders a and b the way a human reads them, treating each run of digits as a single decimal number so "x2" sorts before "x10". It returns -1, 0, or +1 and allocates nothing, handling numbers of any length without overflow.

Example
versions := []string{"v10", "v2", "v1"}
slices.SortFunc(versions, xstrings.CompareNatural)
fmt.Println(versions)

Output:

[v1 v2 v10]

func ContainsAll

func ContainsAll(s string, substrings ...string) bool

ContainsAll reports whether s contains all of the given substrings.

Example
fmt.Println(xstrings.ContainsAll("hello world", "hello", "world"))
fmt.Println(xstrings.ContainsAll("hello world", "hello", "moon"))

Output:

true
false

func ContainsAny

func ContainsAny(s string, substrings ...string) bool

ContainsAny reports whether s contains any of the given substrings.

Example
fmt.Println(xstrings.ContainsAny("hello world", "moon", "world"))
fmt.Println(xstrings.ContainsAny("hello world", "moon", "sun"))

Output:

true
false

func CountAny

func CountAny(s, chars string) int

CountAny returns the number of Unicode code points in s that are contained in chars, following the cutset convention of strings.IndexAny.

Example
fmt.Println(xstrings.CountAny("hello world", "lo"))

Output:

5

func Dedent

func Dedent(s string) string

Dedent strips the longest common leading-whitespace prefix from non-empty lines. Whitespace-only lines are normalized to empty (Python textwrap.dedent).

Dedent("    foo\n      bar\n    baz") // "foo\n  bar\nbaz"
Example
fmt.Println(xstrings.Dedent("    foo\n      bar\n    baz"))

Output:

foo
  bar
baz

func EnsureTrailingNewline

func EnsureTrailingNewline(s string) string

EnsureTrailingNewline trims any trailing newlines from s and appends exactly one, so the result always ends in a single "\n". An empty string becomes "\n".

Example
fmt.Printf("%q\n", xstrings.EnsureTrailingNewline("hello\n\n"))
fmt.Printf("%q\n", xstrings.EnsureTrailingNewline("hello"))

Output:

"hello\n"
"hello\n"

func EqualNatural

func EqualNatural(a, b string) bool

EqualNatural reports whether a and b compare equal in natural order, as decided by CompareNatural. This can differ from a == b, since a numeric run followed by more to compare matches regardless of leading zeros (for example "a00b00" and "a0b00").

Example

Leading zeros are ignored when more text follows the numeric run.

fmt.Println(xstrings.EqualNatural("a00b00", "a0b00"))
fmt.Println(xstrings.EqualNatural("a1", "a2"))

Output:

true
false

func Indent

func Indent(s, prefix string) string

Indent prefixes every non-blank line of s with prefix. Blank and whitespace-only lines are normalized to empty.

Indent("foo\nbar", "  ")      // "  foo\n  bar"
Indent("foo\n\nbar", "> ")    // "> foo\n\n> bar"
Indent("foo\n   \nbar", "> ") // "> foo\n\n> bar"
Example
fmt.Println(xstrings.Indent("foo\nbar", "> "))

Output:

> foo
> bar

func IsBlank

func IsBlank(s string) bool

IsBlank reports whether s is empty or consists only of whitespace.

Example
fmt.Println(xstrings.IsBlank(" \t\n"))
fmt.Println(xstrings.IsBlank("x"))

Output:

true
false

func IsDigits

func IsDigits(s string) bool

IsDigits reports whether s is non-empty and consists entirely of ASCII digits (0-9). An empty string is not digits.

Example
fmt.Println(xstrings.IsDigits("12345"))
fmt.Println(xstrings.IsDigits("12a45"))
fmt.Println(xstrings.IsDigits(""))

Output:

true
false
false

func IsGitCommit

func IsGitCommit(s string) bool

IsGitCommit reports whether s is 40 hexadecimal digits (a Git commit hash).

Example
fmt.Println(xstrings.IsGitCommit("3b18e512dba79e4c8300dd08aeb37f8e728b8dad"))
fmt.Println(xstrings.IsGitCommit("deadbeef"))

Output:

true
false

func IsHex

func IsHex(s string) bool

IsHex reports whether s is non-empty and consists entirely of hexadecimal digits. An empty string is not hex.

Example
fmt.Println(xstrings.IsHex("deadBEEF42"))
fmt.Println(xstrings.IsHex("xyz"))

Output:

true
false

func IsHexChar

func IsHexChar(c rune) bool

IsHexChar reports whether c is a valid hexadecimal digit (0-9, a-f, A-F).

Example
fmt.Println(xstrings.IsHexChar('f'))
fmt.Println(xstrings.IsHexChar('F'))
fmt.Println(xstrings.IsHexChar('9'))
fmt.Println(xstrings.IsHexChar('g'))

Output:

true
true
true
false

func IsSHA256

func IsSHA256(s string) bool

IsSHA256 reports whether s is 64 hexadecimal digits (a SHA-256 digest).

Example
fmt.Println(
    xstrings.IsSHA256("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
)
fmt.Println(xstrings.IsSHA256("deadbeef"))

Output:

true
false

func LessNatural

func LessNatural(a, b string) bool

LessNatural reports whether a sorts before b in natural order, as decided by CompareNatural. It reads cleanly at call sites that want a boolean rather than a three-way result, such as sort predicates and conditionals.

Example
fmt.Println(xstrings.LessNatural("v2", "v10"))
fmt.Println(xstrings.LessNatural("v10", "v2"))

Output:

true
false

func PadCenter

func PadCenter(s string, width int) string

PadCenter pads s with spaces on both sides to width runes, centring it. An odd rune of padding goes on the right. Strings already width runes or longer are returned unchanged.

PadCenter("hi", 5) // " hi  "
Example

PadCenter places the odd rune of padding on the right.

fmt.Printf("%q\n", xstrings.PadCenter("hi", 5))

Output:

" hi  "

func PadLeft

func PadLeft(s string, width int) string

PadLeft pads s with spaces on the left to width runes, right-aligning it. Strings already width runes or longer are returned unchanged. Width is counted in runes; for display-width-aware handling of ANSI text use the ansi package.

PadLeft("hi", 5) // "   hi"
Example
fmt.Printf("%q\n", xstrings.PadLeft("hi", 5))

Output:

"   hi"

func PadRight

func PadRight(s string, width int) string

PadRight pads s with spaces on the right to width runes, left-aligning it. Strings already width runes or longer are returned unchanged.

PadRight("hi", 5) // "hi   "
Example
fmt.Printf("%q\n", xstrings.PadRight("hi", 5))

Output:

"hi   "

func SplitAny

func SplitAny(s, chars string) []string

SplitAny splits s around each occurrence of any Unicode code point in chars, following the cutset convention of strings.IndexAny. Empty segments between adjacent separators are preserved, matching strings.Split semantics. If chars is empty, SplitAny returns a single-element slice containing s.

Example

Empty segments between adjacent separators are preserved.

fmt.Printf("%q\n", xstrings.SplitAny("a,b;;c", ",;"))

Output:

["a" "b" "" "c"]

func SplitBy

func SplitBy(s, sep string) []string

SplitBy splits s by sep, trims whitespace from each part, and drops empty values.

Example
fmt.Printf("%q\n", xstrings.SplitBy(" a | b || c ", "|"))

Output:

["a" "b" "c"]

func SplitCSV

func SplitCSV(s string) []string

SplitCSV splits s on commas, trims whitespace, and drops empty values.

Example
fmt.Printf("%q\n", xstrings.SplitCSV(" a, b ,, c "))

Output:

["a" "b" "c"]

func SplitLines

func SplitLines(s string) []string

SplitLines splits s into non-empty trimmed lines.

Example
fmt.Printf("%q\n", xstrings.SplitLines("foo\n\n  bar \n"))

Output:

["foo" "bar"]

func SplitLinesRaw

func SplitLinesRaw(s string) []string

SplitLinesRaw splits s into lines losslessly, normalizing CRLF to LF: every line is kept verbatim - empty lines and the trailing empty element included - so the result joins back with "\n" without losing content or line numbers.

Example
fmt.Printf("%q\n", xstrings.SplitLinesRaw("foo\r\nbar\n"))

Output:

["foo" "bar" ""]

func Truncate

func Truncate(s string, n int, marker string) string

Truncate is an alias for TruncateRight, the most common form: it keeps the head and trims the tail.

Example
fmt.Println(xstrings.Truncate("hello world", 8, "…"))

Output:

hello w…

func TruncateLeft

func TruncateLeft(s string, n int, marker string) string

TruncateLeft shortens s to at most n runes (including marker) by removing characters from the left, prepending marker when truncation occurs. The tail is kept.

TruncateLeft("hello world", 8, "…") // "…o world"
Example
fmt.Println(xstrings.TruncateLeft("hello world", 8, "…"))

Output:

…o world

func TruncateMiddle

func TruncateMiddle(s string, n int, marker string) string

TruncateMiddle shortens s to at most n runes (including marker) by removing characters from the middle, inserting marker between the kept head and tail so both ends stay visible. This suits hashes and paths, where the start and end are the recognisable parts.

TruncateMiddle("0123456789abcdef", 7, "…") // "012…def"
Example
fmt.Println(xstrings.TruncateMiddle("0123456789abcdef", 7, "…"))

Output:

012…def

func TruncateRight

func TruncateRight(s string, n int, marker string) string

TruncateRight shortens s to at most n runes (including marker) by removing characters from the right, appending marker when truncation occurs. The head is kept. For display-width-aware truncation of ANSI text use ansi.Truncate.

TruncateRight("hello world", 8, "…") // "hello w…"
TruncateRight("hi", 8, "…")          // "hi"
Example
fmt.Println(xstrings.TruncateRight("hello world", 8, "…"))
fmt.Println(xstrings.TruncateRight("hi", 8, "…"))

Output:

hello w…
hi

func Unwrap

func Unwrap(s, prefix, suffix string) (string, bool)

Unwrap returns s with the leading prefix and trailing suffix removed and reports whether both were present. Unlike a strings.TrimPrefix + strings.TrimSuffix chain, nothing is removed unless s starts with prefix AND ends with suffix, so a one-sided match is returned unchanged.

Example
fmt.Println(xstrings.Unwrap(`"quoted"`, `"`, `"`))
fmt.Println(xstrings.Unwrap(`"one-sided`, `"`, `"`))

Output:

quoted true
"one-sided false

Documentation

Overview

Package strings provides string helpers: split, contains, indent/dedent, truncate, and blank checks.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppendCSV

func AppendCSV(dst []string, raw string) []string

AppendCSV splits `raw` on commas, trims whitespace, drops empty values, and appends the remaining values to `dst`.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.AppendCSV([]string{"x"}, " a, b ,, c "))
}
Output:
["x" "a" "b" "c"]

func Closest

func Closest(target string, candidates []string) string

Closest returns the candidate nearest to `target`, suitable for a "did you mean?" suggestion. Distance is the Damerau-Levenshtein (optimal string alignment) edit distance, so an adjacent transposition like "verfiy" counts as one edit, not two - the common typo plain Levenshtein over-penalizes. It returns "" when the nearest candidate is further than a third of `target`'s length in edits, so an unrelated word is never suggested. An empty `target` carries no signal and suggests nothing. Ties resolve to the first candidate.

Closest("verfiy", []string{"verify", "deep"}) // "verify"
Closest("xyzzy", []string{"verify", "deep"})  // ""
Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.Closest("verfiy", []string{"verify", "deep"}))
	fmt.Printf("%q\n", xstrings.Closest("xyzzy", []string{"verify", "deep"}))
}
Output:
"verify"
""

func CompactLines

func CompactLines(s, sep string) string

CompactLines trims lines, drops blank lines, removes duplicate lines while preserving first-seen order, and joins the remaining lines with `sep`.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.CompactLines("  foo \n\nbar\nfoo\n", ", "))
}
Output:
foo, bar

func CompareFold

func CompareFold(a, b string) int

CompareFold compares `a` and `b` case-insensitively, using the same simple case-folding as strings.EqualFold, and returns -1, 0, or 1 following the cmp.Compare convention. `CompareFold(a, b) == 0` iff `strings.EqualFold(a, b)`.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.CompareFold("Go", "go"))
	fmt.Println(xstrings.CompareFold("abc", "ABD"))
	fmt.Println(xstrings.CompareFold("B", "a"))
}
Output:
0
-1
1

func CompareNatural

func CompareNatural(a, b string) int

CompareNatural orders `a` and `b` the way a human reads them, treating each run of digits as a single decimal number so "x2" sorts before "x10". It returns -1, 0, or +1 and allocates nothing, handling numbers of any length without overflow.

Example
package main

import (
	"fmt"
	"slices"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	versions := []string{"v10", "v2", "v1"}
	slices.SortFunc(versions, xstrings.CompareNatural)
	fmt.Println(versions)
}
Output:
[v1 v2 v10]

func ContainsAll

func ContainsAll(s string, substrings ...string) bool

ContainsAll reports whether `s` contains all of the given `substrings`.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.ContainsAll("hello world", "hello", "world"))
	fmt.Println(xstrings.ContainsAll("hello world", "hello", "moon"))
}
Output:
true
false

func ContainsAny

func ContainsAny(s string, substrings ...string) bool

ContainsAny reports whether `s` contains any of the given `substrings`.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.ContainsAny("hello world", "moon", "world"))
	fmt.Println(xstrings.ContainsAny("hello world", "moon", "sun"))
}
Output:
true
false

func CountAny

func CountAny(s, chars string) int

CountAny returns the number of Unicode code points in `s` that are contained in `chars`, following the cutset convention of strings.IndexAny.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.CountAny("hello world", "lo"))
}
Output:
5

func Dedent

func Dedent(s string) string

Dedent strips the longest common leading-whitespace prefix from non-empty lines. Whitespace-only lines are normalized to empty (Python textwrap.dedent).

Dedent("    foo\n      bar\n    baz") // "foo\n  bar\nbaz"
Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.Dedent("    foo\n      bar\n    baz"))
}
Output:
foo
  bar
baz

func EnsureTrailingNewline

func EnsureTrailingNewline(s string) string

EnsureTrailingNewline trims any trailing newlines from `s` and appends exactly one, so the result always ends in a single "\n". An empty string becomes "\n".

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.EnsureTrailingNewline("hello\n\n"))
	fmt.Printf("%q\n", xstrings.EnsureTrailingNewline("hello"))
}
Output:
"hello\n"
"hello\n"

func EqualNatural

func EqualNatural(a, b string) bool

EqualNatural reports whether `a` and `b` compare equal in natural order, as decided by CompareNatural. This can differ from `a == b`, since a numeric run followed by more to compare matches regardless of leading zeros (for example "a00b00" and "a0b00").

Example

Leading zeros are ignored when more text follows the numeric run.

package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.EqualNatural("a00b00", "a0b00"))
	fmt.Println(xstrings.EqualNatural("a1", "a2"))
}
Output:
true
false

func Indent

func Indent(s, prefix string) string

Indent prefixes every non-blank line of `s` with `prefix`. Blank and whitespace-only lines are normalized to empty.

Indent("foo\nbar", "  ")      // "  foo\n  bar"
Indent("foo\n\nbar", "> ")    // "> foo\n\n> bar"
Indent("foo\n   \nbar", "> ") // "> foo\n\n> bar"
Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.Indent("foo\nbar", "> "))
}
Output:
> foo
> bar

func IsBlank

func IsBlank(s string) bool

IsBlank reports whether `s` is empty or consists only of whitespace.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.IsBlank(" \t\n"))
	fmt.Println(xstrings.IsBlank("x"))
}
Output:
true
false

func IsDigits

func IsDigits(s string) bool

IsDigits reports whether `s` is non-empty and consists entirely of ASCII digits (0-9). An empty string is not digits.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.IsDigits("12345"))
	fmt.Println(xstrings.IsDigits("12a45"))
	fmt.Println(xstrings.IsDigits(""))
}
Output:
true
false
false

func IsGitCommit

func IsGitCommit(s string) bool

IsGitCommit reports whether `s` is 40 hexadecimal digits (a Git commit hash).

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.IsGitCommit("3b18e512dba79e4c8300dd08aeb37f8e728b8dad"))
	fmt.Println(xstrings.IsGitCommit("deadbeef"))
}
Output:
true
false

func IsHex

func IsHex(s string) bool

IsHex reports whether `s` is non-empty and consists entirely of hexadecimal digits. An empty string is not hex.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.IsHex("deadBEEF42"))
	fmt.Println(xstrings.IsHex("xyz"))
}
Output:
true
false

func IsHexChar

func IsHexChar(c rune) bool

IsHexChar reports whether `c` is a valid hexadecimal digit (0-9, a-f, A-F).

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.IsHexChar('f'))
	fmt.Println(xstrings.IsHexChar('F'))
	fmt.Println(xstrings.IsHexChar('9'))
	fmt.Println(xstrings.IsHexChar('g'))
}
Output:
true
true
true
false

func IsSHA256

func IsSHA256(s string) bool

IsSHA256 reports whether `s` is 64 hexadecimal digits (a SHA-256 digest).

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(
		xstrings.IsSHA256("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
	)
	fmt.Println(xstrings.IsSHA256("deadbeef"))
}
Output:
true
false

func LessNatural

func LessNatural(a, b string) bool

LessNatural reports whether `a` sorts before `b` in natural order, as decided by CompareNatural. It reads cleanly at call sites that want a boolean rather than a three-way result, such as sort predicates and conditionals.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.LessNatural("v2", "v10"))
	fmt.Println(xstrings.LessNatural("v10", "v2"))
}
Output:
true
false

func PadCenter

func PadCenter(s string, width int) string

PadCenter pads `s` with spaces on both sides to `width` runes, centring it. An odd rune of padding goes on the right. Strings already `width` runes or longer are returned unchanged.

PadCenter("hi", 5) // " hi  "
Example

PadCenter places the odd rune of padding on the right.

package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.PadCenter("hi", 5))
}
Output:
" hi  "

func PadLeft

func PadLeft(s string, width int) string

PadLeft pads `s` with spaces on the left to `width` runes, right-aligning it. Strings already `width` runes or longer are returned unchanged. Width is counted in runes; for display-width-aware handling of ANSI text use the github.com/gechr/x/ansi package.

PadLeft("hi", 5) // "   hi"
Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.PadLeft("hi", 5))
}
Output:
"   hi"

func PadRight

func PadRight(s string, width int) string

PadRight pads `s` with spaces on the right to `width` runes, left-aligning it. Strings already `width` runes or longer are returned unchanged.

PadRight("hi", 5) // "hi   "
Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.PadRight("hi", 5))
}
Output:
"hi   "

func SplitAny

func SplitAny(s, chars string) []string

SplitAny splits `s` around each occurrence of any Unicode code point in `chars`, following the cutset convention of strings.IndexAny. Empty segments between adjacent separators are preserved, matching strings.Split semantics. If `chars` is empty, SplitAny returns a single-element slice containing `s`.

Example

Empty segments between adjacent separators are preserved.

package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.SplitAny("a,b;;c", ",;"))
}
Output:
["a" "b" "" "c"]

func SplitBy

func SplitBy(s, sep string) []string

SplitBy splits `s` by `sep`, trims whitespace from each part, and drops empty values.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.SplitBy(" a | b || c ", "|"))
}
Output:
["a" "b" "c"]

func SplitCSV

func SplitCSV(s string) []string

SplitCSV splits `s` on commas, trims whitespace, and drops empty values.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.SplitCSV(" a, b ,, c "))
}
Output:
["a" "b" "c"]

func SplitLines

func SplitLines(s string) []string

SplitLines splits `s` into non-empty trimmed lines.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.SplitLines("foo\n\n  bar \n"))
}
Output:
["foo" "bar"]

func SplitLinesRaw

func SplitLinesRaw(s string) []string

SplitLinesRaw splits `s` into lines losslessly, normalizing CRLF to LF: every line is kept verbatim - empty lines and the trailing empty element included - so the result joins back with `"\n"` without losing content or line numbers.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Printf("%q\n", xstrings.SplitLinesRaw("foo\r\nbar\n"))
}
Output:
["foo" "bar" ""]

func Truncate

func Truncate(s string, n int, marker string) string

Truncate is an alias for TruncateRight, the most common form: it keeps the head and trims the tail.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.Truncate("hello world", 8, "…"))
}
Output:
hello w…

func TruncateLeft

func TruncateLeft(s string, n int, marker string) string

TruncateLeft shortens `s` to at most `n` runes (including `marker`) by removing characters from the left, prepending `marker` when truncation occurs. The tail is kept.

TruncateLeft("hello world", 8, "…") // "…o world"
Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.TruncateLeft("hello world", 8, "…"))
}
Output:
…o world

func TruncateMiddle

func TruncateMiddle(s string, n int, marker string) string

TruncateMiddle shortens `s` to at most `n` runes (including `marker`) by removing characters from the middle, inserting `marker` between the kept head and tail so both ends stay visible. This suits hashes and paths, where the start and end are the recognisable parts.

TruncateMiddle("0123456789abcdef", 7, "…") // "012…def"
Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.TruncateMiddle("0123456789abcdef", 7, "…"))
}
Output:
012…def

func TruncateRight

func TruncateRight(s string, n int, marker string) string

TruncateRight shortens `s` to at most `n` runes (including `marker`) by removing characters from the right, appending `marker` when truncation occurs. The head is kept. For display-width-aware truncation of ANSI text use github.com/gechr/x/ansi.Truncate.

TruncateRight("hello world", 8, "…") // "hello w…"
TruncateRight("hi", 8, "…")          // "hi"
Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.TruncateRight("hello world", 8, "…"))
	fmt.Println(xstrings.TruncateRight("hi", 8, "…"))
}
Output:
hello w…
hi

func Unwrap

func Unwrap(s, prefix, suffix string) (string, bool)

Unwrap returns `s` with the leading `prefix` and trailing `suffix` removed and reports whether both were present. Unlike a strings.TrimPrefix + strings.TrimSuffix chain, nothing is removed unless `s` starts with `prefix` AND ends with `suffix`, so a one-sided match is returned unchanged.

Example
package main

import (
	"fmt"

	xstrings "github.com/gechr/x/strings"
)

func main() {
	fmt.Println(xstrings.Unwrap(`"quoted"`, `"`, `"`))
	fmt.Println(xstrings.Unwrap(`"one-sided`, `"`, `"`))
}
Output:
quoted true
"one-sided false

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL