Learn how to find all match indexes using regular expressions in Go. Includes examples of regex matching.
last modified April 20, 2025
This tutorial explains how to use the Regexp.FindAllIndex method in Go. We’ll cover its functionality with practical examples.
A regular expression is a sequence of characters that defines a search pattern. It’s used for pattern matching within strings.
The Regexp.FindAllIndex method returns a slice of all successive matches of the pattern in the input byte slice. Each match is represented as a two-element integer slice.
The simplest use of FindAllIndex finds all occurrences of a word. Here we locate all “go” instances in text.
basic_findall.go
package main
import ( “fmt” “regexp” )
func main() {
text := []byte(“go is good, go is great, go is awesome”)
re := regexp.MustCompile(go
)
matches := re.FindAllIndex(text, -1)
for _, match := range matches {
fmt.Printf("Found 'go' at %d-%d\n", match[0], match[1])
}
}
The method returns slice of [start, end] index pairs. Each pair represents one match location in the input text.
FindAllIndex can find multiple different patterns. This example locates both “cat” and “dog” in text.
multiple_patterns.go
package main
import ( “fmt” “regexp” )
func main() {
text := []byte(“cat dog bird cat dog”)
re := regexp.MustCompile(cat|dog
)
matches := re.FindAllIndex(text, -1)
for i, match := range matches {
word := string(text[match[0]:match[1]])
fmt.Printf("Match %d: %s at %d-%d\n", i+1, word, match[0], match[1])
}
}
The alternation operator | matches either pattern. We extract the matched words using the returned indices.
The second parameter controls how many matches to return. Here we limit to first two matches.
limit_matches.go
package main
import ( “fmt” “regexp” )
func main() {
text := []byte(“one two three four five six”)
re := regexp.MustCompile(\w+
)
matches := re.FindAllIndex(text, 2)
for _, match := range matches {
word := string(text[match[0]:match[1]])
fmt.Println(word)
}
}
Setting n to 2 returns only the first two matches. Use -1 to find all matches.
By default, matches don’t overlap. This example shows how to find overlapping matches using lookahead.
overlapping.go
package main
import ( “fmt” “regexp” )
func main() {
text := []byte(“ababab”)
re := regexp.MustCompile((?=(aba))
)
matches := re.FindAllIndex(text, -1)
for _, match := range matches {
// Note: match[0] == match[1] for zero-width matches
fmt.Printf("Found at %d-%d: %s\n",
match[0], match[0]+3, text[match[0]:match[0]+3])
}
}
The lookahead assertion (?=…) allows finding overlapping patterns. Each match has equal start and end indices.
This practical example finds all email addresses in text and their positions.
email_indices.go
package main
import ( “fmt” “regexp” )
func main() {
text := []byte(Contact us at info@example.com or support@company.com
)
re := regexp.MustCompile([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
)
matches := re.FindAllIndex(text, -1)
for _, match := range matches {
email := string(text[match[0]:match[1]])
fmt.Printf("Email %s at %d-%d\n", email, match[0], match[1])
}
}
The pattern matches standard email formats. We extract both the emails and their exact positions in the text.
Empty matches require special handling. This example demonstrates their behavior.
empty_matches.go
package main
import ( “fmt” “regexp” )
func main() {
text := []byte(“a,,b,c,,”)
re := regexp.MustCompile(,
)
matches := re.FindAllIndex(text, -1)
fmt.Println("All comma positions:")
for _, match := range matches {
fmt.Printf("%d-%d\n", match[0], match[1])
}
// Handling empty fields between commas
fields := re.Split(string(text), -1)
fmt.Println("\nFields:")
for i, field := range fields {
fmt.Printf("%d: %q\n", i, field)
}
}
Empty matches appear as zero-length ranges. They’re useful for splitting strings while preserving empty fields.
For large texts, consider using FindAllIndex with byte slices instead of strings for better performance.
performance.go
package main
import ( “fmt” “regexp” “time” )
func main() { // Generate large text var text []byte for i := 0; i < 10000; i++ { text = append(text, “abc123 “…) }
re := regexp.MustCompile(`\d+`)
start := time.Now()
matches := re.FindAllIndex(text, -1)
elapsed := time.Since(start)
fmt.Printf("Found %d matches in %s\n", len(matches), elapsed)
fmt.Printf("First match at %d-%d\n", matches[0][0], matches[0][1])
}
Working with byte slices avoids string conversions. This can significantly improve performance for large inputs.
Go regexp package documentation
This tutorial covered the Regexp.FindAllIndex method in Go with practical examples of pattern matching and index retrieval.
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Go tutorials.