Documentation
¶
Overview ¶
Package strutil provides a small, focused collection of string manipulation helpers for Go, modeled loosely on Laravel's Illuminate\Support\Str facade but translated to idiomatic, rune-safe Go.
All functions are top-level, pure, and handle empty inputs gracefully — there is no package-level state, no init-time side effects, and no global configuration. The only non-stdlib dependency is golang.org/x/text, used solely for Unicode normalization inside Slugify.
Function groups ¶
- Slug and normalization: Slugify, SlugifyN, DefaultMaxSlugLength.
- Case conversion: SnakeCase, KebabCase, CamelCase, StudlyCase, Title, UcFirst, LcFirst.
- Truncation: Truncate, Words, Limit.
- Manipulation: Squish, Finish, Start, After, Before, Between.
- Inspection: ContainsAll, ContainsAny.
- Random: Random (crypto/rand-backed alphanumeric).
Rune safety ¶
Truncation and case conversion iterate runes rather than bytes, so multi-byte UTF-8 strings are handled correctly. Slugify performs NFKD decomposition and strips combining marks, so accented characters transliterate to their ASCII bases (for example, "Café" → "cafe").
Slugify vs KebabCase ¶
Slugify is destructive: it lowercases, transliterates accents, and strips any non-ASCII alphanumeric characters. KebabCase is non-destructive: it preserves multi-byte characters and only changes case and separators.
See the examples directory for runnable demonstrations of each group.
Index ¶
- Constants
- func After(s, search string) string
- func Before(s, search string) string
- func Between(s, start, end string) string
- func CamelCase(s string) string
- func ContainsAll(s string, subs []string) bool
- func ContainsAny(s string, subs []string) bool
- func Finish(s, suffix string) string
- func KebabCase(s string) string
- func LcFirst(s string) string
- func Limit(s string, length int) string
- func Random(length int) string
- func Slugify(s string) string
- func SlugifyN(s string, maxRunes int) string
- func SnakeCase(s string) string
- func Squish(s string) string
- func Start(s, prefix string) string
- func StudlyCase(s string) string
- func Title(s string) string
- func Truncate(s string, length int, suffix string) string
- func UcFirst(s string) string
- func Words(s string, count int, suffix string) string
Constants ¶
const DefaultMaxSlugLength = 80
DefaultMaxSlugLength is a sensible default cap for slug lengths. 80 runes fits comfortably inside VARCHAR(100) columns, keeps URLs readable, and stays well under practical URL-component length limits (~255 bytes on most systems, 2048 for whole URLs). Callers free to choose their own limit via SlugifyN — this constant is a starting point, not a ceiling.
Variables ¶
This section is empty.
Functions ¶
func After ¶
After returns the substring of s after the first occurrence of search. If search is empty or not found, returns s unchanged.
After("hello world", " ") → "world"
After("one.two.three", ".") → "two.three"
After("hello", "z") → "hello"
func Before ¶
Before returns the substring of s before the first occurrence of search. If search is empty or not found, returns s unchanged.
Before("hello world", " ") → "hello"
Before("one.two.three", ".") → "one"
func Between ¶
Between returns the substring of s between start and end markers. It uses the first occurrence of start and the first occurrence of end *after* start. If either marker is missing, returns "".
Between("[hello]", "[", "]") → "hello"
Between("a-b-c", "-", "-") → "b"
Between("no markers", "[", "]") → ""
func CamelCase ¶
CamelCase converts any case style to camelCase.
CamelCase("hello_world") → "helloWorld"
CamelCase("hello-world") → "helloWorld"
CamelCase("Hello World") → "helloWorld"
func ContainsAll ¶
ContainsAll reports whether every substring in subs is present in s. An empty subs slice returns true.
ContainsAll("hello world", []string{"hello", "world"}) → true
ContainsAll("hello world", []string{"hello", "mars"}) → false
func ContainsAny ¶
ContainsAny reports whether at least one substring in subs is present in s. An empty subs slice returns false.
ContainsAny("hello world", []string{"mars", "world"}) → true
ContainsAny("hello world", []string{"mars", "venus"}) → false
func Finish ¶
Finish ensures s ends with suffix, appending it if missing. If s already ends with suffix, returns s unchanged. An empty suffix is a no-op.
Finish("path/to/dir", "/") → "path/to/dir/"
Finish("path/to/dir/", "/") → "path/to/dir/"
func KebabCase ¶
KebabCase converts any case style to kebab-case. Unlike Slugify it does NOT perform Unicode transliteration — multi-byte characters are preserved, only case and separators change.
KebabCase("helloWorld") → "hello-world"
KebabCase("HelloWorld") → "hello-world"
KebabCase("hello_world") → "hello-world"
func LcFirst ¶
LcFirst lowercases the first rune of the string and leaves the rest untouched. Rune-safe for multi-byte input.
LcFirst("Hello") → "hello"
LcFirst("") → ""
func Limit ¶
Limit is Truncate without a suffix — a hard rune cap. Returns s unchanged if it fits within length.
Limit("hello world", 5) → "hello"
func Random ¶
Random returns a cryptographically secure random alphanumeric string of the given length. It uses crypto/rand as the source of entropy and draws from the charset [A-Za-z0-9]. A length of 0 or less returns "". Panics only if the system's crypto/rand is unavailable — a condition that already makes the process unable to function securely.
Random(8) → e.g. "xK2mP9qR" Random(0) → ""
func Slugify ¶
Slugify converts any string to a URL-safe kebab-case slug. It lowercases, NFKD-decomposes to strip accents ("café" → "cafe"), replaces runs of non-alphanumeric characters with single hyphens, and trims leading/trailing hyphens. Returns "" for inputs that normalize to nothing (e.g. "!!!", " ", "").
Examples:
Slugify("Frontend Bug") → "frontend-bug"
Slugify("Café du Monde") → "cafe-du-monde"
Slugify("HELLO_world") → "hello-world"
Slugify(" !! ") → ""
func SlugifyN ¶
SlugifyN behaves like Slugify but caps the result at maxRunes runes. If truncation would leave trailing hyphens (because the cut landed in the middle of a word boundary), those hyphens are stripped so the slug stays well-formed. maxRunes <= 0 returns "".
Examples:
SlugifyN("hello world foo bar", 12) → "hello-world"
SlugifyN("Café du Monde", 10) → "cafe-du-mo"
SlugifyN("abc", 100) → "abc"
SlugifyN("hello", 0) → ""
Use DefaultMaxSlugLength if you don't have a specific column or URL constraint in mind.
func SnakeCase ¶
SnakeCase converts any case style to snake_case.
SnakeCase("helloWorld") → "hello_world"
SnakeCase("HelloWorld") → "hello_world"
SnakeCase("hello-world") → "hello_world"
SnakeCase("hello world") → "hello_world"
func Squish ¶
Squish collapses runs of whitespace (including tabs and newlines) into single spaces and trims leading/trailing whitespace.
Squish(" hello world ") → "hello world"
Squish("line1\n\tline2") → "line1 line2"
func Start ¶
Start ensures s starts with prefix, prepending it if missing. An empty prefix is a no-op.
Start("path/to/file", "/") → "/path/to/file"
Start("/path/to/file", "/") → "/path/to/file"
func StudlyCase ¶
StudlyCase (aka PascalCase) converts any case style to StudlyCase.
StudlyCase("hello_world") → "HelloWorld"
StudlyCase("hello-world") → "HelloWorld"
StudlyCase("hello world") → "HelloWorld"
func Title ¶
Title converts a string to Title Case (each space-separated word capitalized). Does NOT change separators — only capitalization. Underscores and hyphens are not treated as word boundaries.
Title("hello world") → "Hello World"
Title("HELLO WORLD") → "Hello World"
Title("hello_world") → "Hello_world"
func Truncate ¶
Truncate returns s truncated to at most length runes (not bytes), appending suffix if truncation actually happened. If s fits within length, it is returned unchanged. length is measured in runes so multi-byte UTF-8 is safe.
Truncate("hello world", 5, "...") → "hello..."
Truncate("hello", 10, "...") → "hello"
Truncate("café", 3, "…") → "caf…"
func UcFirst ¶
UcFirst capitalizes the first rune of the string and leaves the rest untouched. Rune-safe for multi-byte input.
UcFirst("hello") → "Hello"
UcFirst("") → ""
func Words ¶
Words returns s truncated to at most count words, appending suffix if truncation happened. Words are split on any whitespace; leading, trailing, and interior runs of whitespace collapse during splitting.
Words("the quick brown fox", 2, "...") → "the quick..."
Words("hello", 5, "...") → "hello"
Types ¶
This section is empty.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
case
command
Package main demonstrates the case-conversion helpers: SnakeCase, KebabCase, CamelCase, StudlyCase, Title, UcFirst, LcFirst.
|
Package main demonstrates the case-conversion helpers: SnakeCase, KebabCase, CamelCase, StudlyCase, Title, UcFirst, LcFirst. |
|
inspect
command
Package main demonstrates the inspection helpers: ContainsAll, ContainsAny.
|
Package main demonstrates the inspection helpers: ContainsAll, ContainsAny. |
|
manipulate
command
Package main demonstrates the manipulation helpers: Squish, Finish, Start, After, Before, Between.
|
Package main demonstrates the manipulation helpers: Squish, Finish, Start, After, Before, Between. |
|
random
command
Package main demonstrates Random: a cryptographically secure alphanumeric string generator backed by crypto/rand.
|
Package main demonstrates Random: a cryptographically secure alphanumeric string generator backed by crypto/rand. |
|
slugify
command
Package main demonstrates Slugify and SlugifyN: NFKD-based URL slug generation with an optional rune cap.
|
Package main demonstrates Slugify and SlugifyN: NFKD-based URL slug generation with an optional rune cap. |
|
truncate
command
Package main demonstrates the truncation helpers: Truncate, Words, Limit.
|
Package main demonstrates the truncation helpers: Truncate, Words, Limit. |