在GO中捕获重复组

时间:2018-11-22 15:40:47

标签: regex go

我正在尝试创建一个函数,该函数可以解析由大写单词后跟零个或多个用双引号引起来的参数组成的字符串。

例如,以下各行:

COPY "filename one" "filename two"
REMOVE "filename"
LIST "x" "y" "z"
DISCONNECT

结果应为字符串(命令),后跟字符串[](引号内的参数)。我创建了以下正则表达式:

re1, _ := regexp.Compile(`([A-Z]+)(?: "([^"]+)")*`)
results := re1.FindAllStringSubmatch(input, -1)

但是,无论如何,我只会尝试捕获最后一个参数。

我的问题的一个示例:https://play.golang.org/p/W1rE1X4SWf5

在此示例中未捕获

"arg1"。我想念什么?

4 个答案:

答案 0 :(得分:2)

如果您的命令定义正确,例如命令名称始终为大写,参数始终位于命令之后,然后使用宽松的正则表达式可能恰好适合您的用例:

re1, _ := regexp.Compile(`([A-Z]+)|(?: "([^"]+)")`)
results := re1.FindAllStringSubmatch(`COMMAND "arg1" "arg2" "arg3"`, -1)

fmt.Println("Command:", results[0][1])
for _, arg := range results[1:] {
    fmt.Println("Arg:", arg[2])
}

Playground

答案 1 :(得分:1)

当您尝试捕获重复的比赛时,只会捕获最后一个。  我将尝试分两个步骤进行操作:首先将commmand和参数分开,然后解析参数。

使用SELECT DISTINCT( itemid ) FROM itemorders WHERE orderid NOT IN (SELECT orderid FROM itemdelivered) demo)可以拆分命令和参数:

  • ([A-Z]+)((?: "[^"]+")*)在第一组中,您将获得命令
  • ([A-Z]+)在第二组中,您将使用引号将参数引起来,并用空格分隔

然后,您可以将((?: "[^"]+")*)FindAllString一起使用以提取参数(demo)。

答案 2 :(得分:1)

我认为这可以解决您的问题

re1, _ := regexp.Compile(`([A-Z]+)(?: *)`)
commandText:=`COPY "filename one" "filename two"`
if re1.Match([]byte(commandText)){
    index:=re1.FindIndex([]byte(commandText))[1]
    commandArgs:=commandText[index:]
    commandArgsRegex,_:=regexp.Compile(`"([^"]+)"`)
    fmt.Println("Command= " , commandText[0:index])
    for i,arg:=range commandArgsRegex.FindAllString(commandArgs,-1){
        fmt.Println("args ", i,"= " , arg)
    }
}else{
    fmt.Println("Failed")
}

答案 3 :(得分:0)

添加一个额外的捕获组。如果将其设置为可选,则多余的数据将为空,但匹配将起作用

require 'nokogiri'
module InlineSvgHelper
  def the_inline_svg(path, css="")
    doc = Nokogiri::XML(File.read("public#{path}"))
    svg = doc.at_css "svg"
    svg['class'] = "#{css}"
    return raw doc
  end
end

添加更多<%= the_inline_svg("public#{asset_pack_path('images/grapes.svg')}", 'h-1/4 w-1/4') %>表达式,直至达到所需的最大值。我输入两个,因为示例中有一个带有3个参数的表达式