strings.Trim entfernt vom Anfang und Ende eines Strings solange Zeichen, wie diese im übergebenen Cutset enthalten sind. Sobald an einer Seite ein Zeichen auftaucht, das nicht im Cutset steckt, hält das Trimmen für diese Seite an. Die Funktion arbeitet vollständig rune-aware: Der Cutset wird als Folge von Unicode-Codepoints interpretiert, nicht als Byte-Folge, weshalb auch Umlaute, kyrillische Zeichen oder Emojis problemlos als Trim-Zeichen funktionieren.

Die mit Abstand häufigste Falle liegt im Verständnis des Parameters: Der Cutset ist eine Menge einzelner Runes, kein Substring. Wer Trim(s, "file") schreibt, entfernt nicht das Wort file an den Rändern, sondern jedes einzelne Vorkommen der Zeichen f, i, l und e. Für das Abschneiden ganzer Substrings ist TrimPrefix bzw. TrimSuffix zuständig — eine Unterscheidung, die in Reviews regelmässig zu Bugs führt.

Die Signatur ist denkbar schlank: zwei Strings rein, ein String raus. Der zweite Parameter heisst zwar cutset string, wird intern aber sofort in einen Rune-Set zerlegt — der String ist nur die kompakteste Schreibweise einer Menge von Codepoints.

Go signature.go
func Trim(s, cutset string) string

Der Rückgabewert ist entweder der getrimmte Teil-String (als neuer Header, aber auf dem gleichen Backing-Array) oder — wenn nichts zu trimmen war — s selbst unverändert. Eine Allokation findet nur statt, wenn tatsächlich Zeichen abgeschnitten werden.

Der Cutset-String wird zeichenweise als Set interpretiert. Reihenfolge und Duplikate spielen keine Rolle: "abc", "cba" und "aabbcc" ergeben denselben Set {a, b, c}. Trim läuft dann von links und rechts solange weiter, bis jeweils ein Zeichen ausserhalb dieses Sets erreicht wird.

Go cutset_falle.go
package main

import (
	"fmt"
	"strings"
)

func main() {
	// Cutset = Menge {f, i, l, e} - jedes dieser Zeichen wird entfernt
	fmt.Printf("%q\n", strings.Trim("effective.go", "file"))

	// Cutset = Menge {., g, o}
	fmt.Printf("%q\n", strings.Trim("effective.go", ".go"))

	// Wer wirklich das Wort "file" entfernen will, braucht TrimPrefix
	fmt.Printf("%q\n", strings.TrimPrefix("file_handler.go", "file"))
}
Output
"ctiv.go"
"effective"
"_handler.go"

Im ersten Beispiel wird links eff und rechts e.go (genauer: e, ., g, o von rechts) abgeschnitten, bis links das c und rechts das v stehen — beides nicht im Cutset. Das zweite Beispiel zeigt, wie sich Reihenfolge im Cutset nicht auswirkt: .go ist nur Notation für die Menge {., g, o}.

Go-Strings sind UTF-8-codiert, und Trim dekodiert den Cutset korrekt in Runes. Multi-Byte-Codepoints lassen sich daher genauso natürlich als Trim-Zeichen verwenden wie ASCII-Zeichen — ohne dass man sich um die Byte-Länge kümmern muss.

Go rune_aware.go
package main

import (
	"fmt"
	"strings"
)

func main() {
	// Umlaute im Cutset
	fmt.Printf("%q\n", strings.Trim("äöüHalloüöä", "äöü"))

	// Emoji im Cutset
	fmt.Printf("%q\n", strings.Trim("🌟🌟Mibeon🌟", "🌟"))

	// Gemischt: ASCII + Multi-Byte
	fmt.Printf("%q\n", strings.Trim("--→Pfad→--", "-→"))
}
Output
"Hallo"
"Mibeon"
"Pfad"

Würde Trim byteweise arbeiten, würden Umlaute fälschlich an einzelnen Bytes gespalten. Die Rune-aware-Implementierung garantiert, dass ä (zwei Bytes in UTF-8) als ein einziges Trim-Zeichen behandelt wird.

Ist der Cutset ein leerer String, ist die Menge leer — und kein Zeichen kann gematcht werden. Trim gibt dann den Original-String unverändert zurück, ohne Allokation und ohne Whitespace-Sonderbehandlung.

Go leerer_cutset.go
package main

import (
	"fmt"
	"strings"
)

func main() {
	s := "  hallo  "
	out := strings.Trim(s, "")

	fmt.Printf("%q\n", out)
	fmt.Println(out == s) // identisch, keine Veränderung
}
Output
"  hallo  "
true

Wer Whitespace trimmen will, braucht TrimSpace — das nutzt intern einen festen Cutset gemäss unicode.IsSpace und behandelt damit auch exotische Whitespace-Codepoints wie U+00A0 (NBSP) korrekt.

Die Trim-Familie wirkt auf den ersten Blick redundant, jede Variante hat aber einen klar abgegrenzten Anwendungsfall. Die folgende Tabelle hilft, die richtige Funktion ohne Nachdenken zu wählen.

FunktionWas entfernt wirdWoArgument-Typ
Trim(s, cutset)jedes Zeichen aus Cutsetlinks + rechtsRune-Set
TrimLeft(s, cutset)jedes Zeichen aus Cutsetnur linksRune-Set
TrimRight(s, cutset)jedes Zeichen aus Cutsetnur rechtsRune-Set
TrimSpace(s)alle Unicode-Whitespaceslinks + rechtsfix (intern)
TrimPrefix(s, prefix)genau dieser Substringnur links, einmaligSubstring
TrimSuffix(s, suffix)genau dieser Substringnur rechts, einmaligSubstring
TrimFunc(s, f)Runes, für die f true istlinks + rechtsPrädikat

Faustregel: Sobald „ein ganzes Wort entfernen" gemeint ist, gehört der Aufruf nach TrimPrefix/TrimSuffix. Geht es um „beliebige Anführungs- oder Trennzeichen weg", ist Trim die richtige Wahl.

Beim Parsen halb-strukturierter Daten — etwa Werten aus einer rudimentären INI-Datei, Shell-Output oder einem ungewaschenen JSON-Snippet — sind Werte häufig noch von doppelten oder einfachen Anführungszeichen umschlossen. Trim mit Cutset "\"'" löst das in einer Zeile, unabhängig davon, ob doppelte oder einfache Quotes verwendet wurden.

Go praxis_quotes.go
package main

import (
	"fmt"
	"strings"
)

func unquote(s string) string {
	return strings.Trim(s, "\"'")
}

func main() {
	werte := []string{
		`"mibeon.de"`,
		`'localhost'`,
		`"quoted'mixed"`,
		`ohneQuotes`,
	}

	for _, v := range werte {
		fmt.Printf("%-20s -> %q\n", v, unquote(v))
	}
}
Output
"mibeon.de"          -> "mibeon.de"
'localhost'          -> "localhost"
"quoted'mixed"       -> "quoted'mixed"
ohneQuotes           -> "ohneQuotes"

Beachte: Da der Cutset eine Menge ist, behandelt der Aufruf gemischte Quote-Paare genauso korrekt wie symmetrische — und Strings ohne Quotes bleiben unverändert. Für echtes JSON ist strconv.Unquote natürlich robuster (Escapes!), aber für hauseigene Formate ist diese Ein-Zeilen-Lösung Gold wert.

Vor allem beim Bauen von URLs oder beim Joinen von Pfadsegmenten will man führende und schliessende Slashes weghaben, bevor man Teile mit einem definierten Separator zusammensetzt. Trim(s, "/") ist hier die idiomatische Lösung und stabil gegenüber mehrfachen Slashes.

Go praxis_slashes.go
package main

import (
	"fmt"
	"strings"
)

func joinPath(parts ...string) string {
	cleaned := make([]string, 0, len(parts))
	for _, p := range parts {
		p = strings.Trim(p, "/")
		if p != "" {
			cleaned = append(cleaned, p)
		}
	}
	return "/" + strings.Join(cleaned, "/")
}

func main() {
	fmt.Println(joinPath("/api/", "/v2/", "users/", "/42"))
	fmt.Println(joinPath("docs", "///go///", "stdlib", "strings"))
}
Output
/api/v2/users/42
/docs/go/stdlib/strings

Weil Trim solange schneidet, wie das Zeichen matcht, fallen auch Mehrfach-Slashes wie ///go/// zuverlässig weg. Für komplexere Pfadlogik mit ..-Auflösung gehört der Aufruf zwar nach path.Clean, doch für reines Rand-Trimmen ist strings.Trim schneller und expliziter.

Cutset ist Menge, nicht Substring

Trim(s, "abc") entfernt jedes einzelne a, b, c an den Rändern — nicht das Wort abc. Reihenfolge und Duplikate im Cutset-String sind bedeutungslos.

Häufigste Verwechslung: TrimPrefix

Wer einen ganzen Substring vom Anfang abschneiden will, braucht TrimPrefix(s, prefix). Trim ist für diesen Zweck das falsche Werkzeug und führt zu subtilen Bugs.

Rune-aware: Multi-Byte funktioniert

Der Cutset wird als UTF-8 dekodiert. Umlaute, kyrillische Zeichen, Emojis — alles geht als Trim-Zeichen, ohne Byte-Gefriemel.

Entfernt solange Zeichen matchen

Trim hält an jeder Seite erst an, wenn das erste Nicht-Cutset-Zeichen erreicht ist. Mehrfaches Vorkommen am Rand wird komplett entfernt.

Leerer Cutset = s unverändert

Trim(s, "") gibt s ohne Allokation zurück. Whitespace wird dabei nicht behandelt — dafür gibt es TrimSpace.

TrimSpace ist der Whitespace-Spezialfall

Statt Trim(s, " \t\n\r") lieber TrimSpace(s) — das deckt sämtliche Unicode-Whitespaces inkl. NBSP korrekt ab.

Allokiert nur, wenn getrimmt wurde

Wenn am Rand nichts zu schneiden ist, wird s byteweise identisch zurückgegeben — der Header zeigt auf dasselbe Backing-Array.

Threadsafe / pure Funktion

Trim mutiert nichts und hängt nur von den Eingaben ab. Beliebig parallel aufrufbar, auch auf demselben Quell-String.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Das strings-Paket — String-Manipulation

Zur Übersicht