Golang:为什么regexp.FindAllStringSubmatch()返回[] []字符串而不是[]字符串?

时间:2017-08-24 08:20:40

标签: regex go

我有点新手,这是我第一次处理正则表达式。

我有点惊讶someregex.FindAllStringSubmatch("somestring", -1)返回切片[][]string而不是简单的字符串切片:[]string

示例:

someRegex, _ := regexp.Compile("^.*(mes).*$")
matches := someRegex.FindAllStringSubmatch("somestring", -1)
fmt.Println(matches) // logs [[somestring mes]]

这种行为的原因是什么,我无法弄明白?

2 个答案:

答案 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表示不匹配。

Docs

总结:您需要一个字符串数组数组,因为这是FindStringSubmatch的所有版本。 FindStringSubmatch将返回单个字符串数组。