Golang Regexp.FindAllStringIndex
最后修改于 2025 年 4 月 20 日
本教程解释了如何在 Go 中使用 Regexp.FindAllStringIndex 方法。我们将介绍它的功能并提供实际示例。
一个 正则表达式 是一个定义搜索模式的字符序列。它用于在字符串中进行模式匹配。
Regexp.FindAllStringIndex 方法返回输入字符串中模式的所有连续匹配项的切片。每次匹配都表示为一个两元素整数切片。
基本 FindAllStringIndex 示例
FindAllStringIndex 最简单的用法是查找单词的所有匹配项。这里我们定位字符串中 "go" 的所有出现。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`go`)
text := "go learn go, go golang"
matches := re.FindAllStringIndex(text, -1)
fmt.Println(matches) // [[0 2] [8 10] [13 15]]
}
该方法返回一个切片数组,其中每个内部切片包含匹配项的开始和结束索引。第二个参数 -1 表示查找所有匹配项。
查找多个单词的出现
此示例演示了在字符串中查找多个不同单词。我们搜索 "cat" 或 "dog" 的所有出现。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`cat|dog`)
text := "I have a cat and a dog. My cat likes my dog."
matches := re.FindAllStringIndex(text, -1)
for _, match := range matches {
fmt.Printf("Found %q at %d-%d\n",
text[match[0]:match[1]], match[0], match[1])
}
}
交替运算符 | 匹配 "cat" 或 "dog"。我们打印每次匹配及其在原始字符串中的位置。
查找电子邮件位置
我们可以使用 FindAllStringIndex 在文本中定位电子邮件地址。此示例显示了如何查找它们的位置。
package main
import (
"fmt"
"regexp"
)
func main() {
pattern := `[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}`
re := regexp.MustCompile(pattern)
text := "Contact us at info@example.com or support@company.org"
matches := re.FindAllStringIndex(text, -1)
for _, match := range matches {
fmt.Println("Email found at positions:", match[0], "to", match[1])
fmt.Println("Email:", text[match[0]:match[1]])
}
}
该模式匹配标准的电子邮件格式。我们从文本中提取位置和实际的电子邮件地址。
限制匹配数量
FindAllStringIndex 的第二个参数可以限制返回的匹配数量。在这里,我们只查找前两个数字。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\d+`)
text := "100 200 300 400 500"
// Find first two number matches
matches := re.FindAllStringIndex(text, 2)
fmt.Println(matches) // [[0 3] [4 7]]
}
我们不传递 -1 来查找所有匹配项,而是传递 2 来只获取前两个匹配项。该方法在找到指定数量的匹配项后停止搜索。
查找重叠匹配项
默认情况下,匹配项不重叠。此示例展示了如何使用前瞻断言查找重叠匹配项。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`(?=(\d\d\d))`)
text := "12345"
matches := re.FindAllStringIndex(text, -1)
for _, match := range matches {
fmt.Println("Match at:", match[0], "to", match[1])
fmt.Println("Triplet:", text[match[0]:match[0]+3])
}
}
前瞻断言 (?=...) 允许查找所有可能的 3 位数字序列。此技术对于查找文本中的重叠模式很有用。
查找单词边界
此示例演示了如何使用单词边界标记查找整个单词及其位置。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\b\w+\b`)
text := "The quick brown fox jumps"
matches := re.FindAllStringIndex(text, -1)
for i, match := range matches {
word := text[match[0]:match[1]]
fmt.Printf("Word %d: %q at %d-%d\n", i+1, word, match[0], match[1])
}
}
\b 标记确保我们只匹配整个单词。我们打印每个单词及其在原始字符串中的位置。
处理空匹配
在某些情况下,FindAllStringIndex 可能会返回空匹配。此示例显示了如何正确处理它们。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`a*`)
text := "baaab"
matches := re.FindAllStringIndex(text, -1)
for i, match := range matches {
if match[0] == match[1] {
fmt.Printf("Empty match at position %d\n", match[0])
} else {
fmt.Printf("Match %d: %q at %d-%d\n",
i, text[match[0]:match[1]], match[0], match[1])
}
}
}
a* 模式匹配零个或多个 'a',这会导致空匹配。我们通过比较开始和结束索引来检查空匹配。
来源
本教程通过实际的模式匹配和位置查找示例,涵盖了 Go 中的 Regexp.FindAllStringIndex 方法。