我有点新手,这是我第一次处理正则表达式。
我有点惊讶someregex.FindAllStringSubmatch("somestring", -1)
返回切片[][]string
而不是简单的字符串切片:[]string
。
示例:
someRegex, _ := regexp.Compile("^.*(mes).*$")
matches := someRegex.FindAllStringSubmatch("somestring", -1)
fmt.Println(matches) // logs [[somestring mes]]
这种行为的原因是什么,我无法弄明白?
答案 0 :(得分:4)
func (*Regexp) FindAllStringSubmatch
提取匹配和捕获的子匹配。
子匹配是正则表达式部分匹配的文本的一部分,正则表达式部分用一对未转义的括号(所谓的capturing group)括起来。
在您的情况下,^.*(mes).*$
匹配:
^
- 字符串开头.*
- 尽可能多的0个字符(mes)
- 捕获第1组:mes
子字符串.*$
- 字符串的其余部分。因此,匹配值是整个字符串。它将是输出中的第一个值。然后,由于有一个捕获组,结果中必须有一个位置,因此,mes
被放置为列表中的第二个项目。
由于可能有多于1的匹配,我们需要一个列表列表。
一个更好的例子可能是具有多个匹配/子匹配提取的那个(也可能是一个可选组):
package main
import (
"fmt"
"regexp"
)
func main() {
someRegex, _ := regexp.Compile(`[^aouiye]([aouiye])([^aouiye])?`)
matches := someRegex.FindAllStringSubmatch("somestri", -1)
fmt.Printf("%q\n", matches)
}
[^aouiye]([aouiye])([^aouiye])?
匹配非元音,元音和非元音,将最后2个捕获到单独的组#1和#2中。
结果为[["som" "o" "m"] ["ri" "i" ""]]
。有2个匹配,每个匹配包含匹配值,组1值和组2值。由于ri
匹配没有捕获到第2组(([^aouiye])?
)的文本,因此它是空的,但它仍然存在,因为该组是以正则表达式模式定义的。
答案 1 :(得分:2)
FindAllStringSubmatch是FindStringSubmatch的'All'版本;它 返回表达式的所有连续匹配的切片,如 由包评论中的“全部”描述定义。回报 值为nil表示不匹配。
总结:您需要一个字符串数组数组,因为这是FindStringSubmatch的所有版本。 FindStringSubmatch将返回单个字符串数组。