strings.Index în Go

Returnează poziția (în octeți) a primei sau ultimei apariții a unui text, octet sau caracter; -1 dacă nu există.

Sintaxă
func Index(s, substr string) int
func LastIndex(s, substr string) int
func IndexByte(s string, c byte) int
func LastIndexByte(s string, c byte) int
func IndexRune(s string, r rune) int

Ce face strings.Index

strings.Index(s, substr) returnează poziția primei apariții a lui substr în s, iar strings.LastIndex poziția ultimei apariții. Dacă textul nu este găsit, ambele returnează -1. Pozițiile încep de la 0.

Foarte important: poziția este numărată în octeți, nu în caractere. În Go textele sunt UTF-8, iar literele românești ă, â, î, ș, ț ocupă câte 2 octeți. În „Brașov și Iași”, „Iași” începe la octetul 12, deși are 10 caractere înainte. Poziția este exact ce îți trebuie pentru a tăia textul cu s[i:], dar nu este numărul caracterului.

Variantele: IndexByte și LastIndexByte caută un singur octet (un caracter ASCII ca ',' sau '/'), foarte rapid; IndexRune caută un caracter Unicode ('ș'). Pentru „oricare dintre caractere” sau „primul caracter care respectă o condiție” vezi strings.IndexAny.

Parametri

Parametru Descriere
s Textul în care se caută.
substr Textul căutat (la Index și LastIndex).
c Octetul căutat (la IndexByte și LastIndexByte).
r Caracterul căutat (la IndexRune).

Ce returnează

Poziția în octeți (int) a apariției găsite sau -1.

Exemple

Exemplul 1: Prima și ultima apariție

package main

import (
	"fmt"
	"strings"
)

func main() {
	traseu := "Iași - Bacău - Brașov - Bacău"
	fmt.Println(strings.Index(traseu, "Bacău"))
	fmt.Println(strings.LastIndex(traseu, "Bacău"))
	fmt.Println(strings.Index(traseu, "Cluj"))

	cale := "/home/ana/documente/note.txt"
	i := strings.LastIndexByte(cale, '/')
	fmt.Println("director:", cale[:i], "| fișier:", cale[i+1:])
	fmt.Println("primul punct:", strings.IndexByte(cale, '.'))
}

Rezultat

8
27
-1
director: /home/ana/documente | fișier: note.txt
primul punct: 24

Exemplul 2: Poziția este în octeți, nu în caractere

Înainte de „Iași” sunt 10 caractere, dar 12 octeți, pentru că cele două litere ș ocupă câte 2 octeți. Tăierea s[i:] funcționează corect; pentru numărul de caractere folosim utf8.RuneCountInString.

package main

import (
	"fmt"
	"strings"
	"unicode/utf8"
)

func main() {
	s := "Brașov și Iași"
	i := strings.Index(s, "Iași")
	fmt.Println("poziția în octeți:", i)
	fmt.Println("caractere înainte:", utf8.RuneCountInString(s[:i]))
	fmt.Println("de la poziție:", s[i:])
	fmt.Println("IndexRune('ș'):", strings.IndexRune(s, 'ș'))
	fmt.Println("len(s) =", len(s), "octeți, dar", utf8.RuneCountInString(s), "caractere")
}

Rezultat

poziția în octeți: 12
caractere înainte: 10
de la poziție: Iași
IndexRune('ș'): 3
len(s) = 17 octeți, dar 14 caractere

Exemplul 3: Extragerea unui text dintre două marcaje

package main

import (
	"fmt"
	"strings"
)

func main() {
	html := "<title>Învață Go</title>"
	start := strings.Index(html, "<title>")
	end := strings.Index(html, "</title>")
	if start >= 0 && end > start {
		titlu := html[start+len("<title>") : end]
		fmt.Println("Titlul:", titlu)
	}
}

Rezultat

Titlul: Învață Go

Greșeli frecvente

  • Folosești rezultatul ca număr de caractere: „al câtelea caracter este?”. Pe text cu diacritice răspunsul este greșit, pentru că Index numără octeți. Folosește utf8.RuneCountInString(s[:i]).
  • Nu verifici -1 și tai direct s[i:]. Dacă textul nu există, s[-1:] oprește programul cu panic.
  • Folosești IndexByte(s, 'ș'). Litera ș nu încape într-un octet, deci nu compilează; folosește IndexRune.

Comenzi înrudite

  • strings.IndexAny: Poziția primului sau ultimului caracter dintr-un set (IndexAny) ori care respectă o condiție (IndexFunc); -1 dacă nu există.
  • strings.Contains: Verifică dacă un text conține un alt text, unul dintre niște caractere, un caracter anume sau un caracter care respectă o condiție.
  • strings.Cut: Taie textul în două la prima (Cut) sau ultima (CutLast) apariție a separatorului și spune dacă l-a găsit.
  • unicode/utf8.RuneCountInString: Numără caracterele (rune) dintr-un text UTF-8; len() numără octeții, iar ă, î, ș, ț ocupă câte 2 octeți.