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 directs[i:]. Dacă textul nu există,s[-1:]oprește programul cupanic. - Folosești
IndexByte(s, 'ș'). Litera ș nu încape într-un octet, deci nu compilează; foloseșteIndexRune.
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.