Golang Regexp.FindStringIndex
最后修改于 2025 年 4 月 20 日
本教程解释了如何在 Go 中使用 Regexp.FindStringIndex
方法。我们将介绍它的用途并提供实际的用法示例。
一个 正则表达式 是一个定义搜索模式的字符序列。它用于在字符串中进行模式匹配。
Regexp.FindStringIndex
方法返回一个由两个整数组成的切片,定义了字符串中最左边匹配项的位置。第一个元素是起始索引,第二个元素是结束索引。
基本的 FindStringIndex 示例
FindStringIndex
最简单的用法是查找单词的位置。这里我们定位“world”的第一次出现。
package main import ( "fmt" "regexp" ) func main() { re := regexp.MustCompile(`world`) str := "hello world, welcome to the world of Go" indices := re.FindStringIndex(str) fmt.Println(indices) // [6 11] if indices != nil { fmt.Println("Found at:", indices[0], "to", indices[1]) fmt.Println("Matched:", str[indices[0]:indices[1]]) } }
该方法返回 [6 11],表示匹配从索引 6 开始到索引 11 结束。如果没有找到匹配项,则返回 nil。我们可以使用这些索引来切片字符串。
查找多个出现
要查找所有出现次数,我们使用 FindAllStringIndex
。此示例查找所有“go”匹配项(不区分大小写)。
package main import ( "fmt" "regexp" ) func main() { re := regexp.MustCompile(`(?i)go`) str := "Go to the GO store and buy golang GO" allIndices := re.FindAllStringIndex(str, -1) for i, loc := range allIndices { fmt.Printf("Match %d: %v, text: %s\n", i+1, loc, str[loc[0]:loc[1]]) } }
(?i)
使匹配不区分大小写。我们获得了四个匹配项及其位置。第二个参数(-1)表示查找所有匹配项。
使用子匹配项查找索引
此示例显示了如何获取捕获组的索引。我们解析日期字符串。
package main import ( "fmt" "regexp" ) func main() { re := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`) date := "Event date: 2025-04-20" // Get indices for full match and submatches indices := re.FindStringSubmatchIndex(date) if indices != nil { fmt.Println("Full match:", indices[0:2]) fmt.Println("Year:", indices[2:4], date[indices[2]:indices[3]]) fmt.Println("Month:", indices[4:6], date[indices[4]:indices[5]]) fmt.Println("Day:", indices[6:8], date[indices[6]:indices[7]]) } }
FindStringSubmatchIndex
为每个捕获组返回索引对。偶数索引是起始位置,奇数索引是匹配的结束位置。
查找第一个数字的索引
此示例查找字符串中第一个数字的位置。它演示了简单的模式匹配。
package main import ( "fmt" "regexp" ) func main() { re := regexp.MustCompile(`\d`) str := "Product ID: A42B-789C" loc := re.FindStringIndex(str) if loc != nil { fmt.Println("First digit at position:", loc[0]) fmt.Println("Digit is:", str[loc[0]:loc[1]]) } else { fmt.Println("No digits found") } }
模式 \d
匹配任何数字。该方法返回第一个匹配项的位置(在此示例中为 14)。然后我们可以提取该数字。
在文本中查找 URL 索引
此示例查找文本块中的所有 HTTP/HTTPS URL。它展示了一个更复杂的带索引的模式。
package main import ( "fmt" "regexp" ) func main() { re := regexp.MustCompile(`https?://[^\s]+`) text := `Visit https://example.com or http://test.org for more info.` urls := re.FindAllStringIndex(text, -1) for _, loc := range urls { fmt.Printf("URL found at %v: %s\n", loc, text[loc[0]:loc[1]]) } }
该模式匹配 http:// 或 https:// 后跟非空白字符。我们获取文本中两个 URL 的确切位置以进行进一步处理。
验证和提取电子邮件位置
此示例验证电子邮件并显示其位置。它结合了匹配和索引提取。
package main import ( "fmt" "regexp" ) func main() { re := regexp.MustCompile(`\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b`) text := `Contact us at info@example.com or support@company.co.uk` emails := re.FindAllStringIndex(text, -1) for i, loc := range emails { fmt.Printf("Email %d: %s (positions %d-%d)\n", i+1, text[loc[0]:loc[1]], loc[0], loc[1]) } }
该模式匹配标准的电子邮件格式。我们获取电子邮件地址及其在输入字符串中的确切位置,用于验证或提取。
查找重叠匹配项
这个高级示例演示了如何通过手动调整搜索位置来查找重叠匹配项。我们在“banana”中查找所有“ana”。
package main import ( "fmt" "regexp" ) func main() { re := regexp.MustCompile(`ana`) str := "banana" pos := 0 for pos < len(str) { loc := re.FindStringIndex(str[pos:]) if loc == nil { break } actualStart := pos + loc[0] actualEnd := pos + loc[1] fmt.Printf("Found at %d-%d: %s\n", actualStart, actualEnd, str[actualStart:actualEnd]) pos += loc[0] + 1 // Move just past current match start } }
通过搜索子字符串和调整位置,我们找到了所有匹配项,包括重叠的匹配项。这项技术对于某些模式匹配任务很有用。
来源
本教程通过使用正则表达式查找字符串位置的实际示例,涵盖了 Go 中的 Regexp.FindStringIndex
方法。