1

我正在制作一种简单的基于堆栈的语言,它使用命令来操作堆栈。当我在源代码中找到命令时,我使用这个正则表达式来分离出实际的命令名称,例如sum和命令的参数。参数用三角括号括起来并用逗号分隔。

这是我目前正在使用的正则表达式:

(?<command>[^<>\s]+)(\<(?<args>(\d+)+(?>,\s*\d+)*)\>)?

现在这工作正常,这里有一些它工作的例子:

+              => command: '+', args: nil
sum<5>         => command: 'sum', args: '5'
print<1, 2, 3> => command: 'print', args: '1, 2, 3'

这完全符合我对除最后一个之外的每一个的要求。我的问题是,有没有办法分别捕获每个参数?我的意思是这样的:

print<1, 2, 3> => command: 'print', args: ['1', '2', '3']

顺便说一句,我正在使用最新的 Ruby 正则表达式引擎。

4

1 回答 1

1

由于引擎不保留捕获堆栈,因此在 Ruby 正则表达式中使用具有重复捕获组的简单正则表达式是不可能获得这样的输出的。

您需要将第二个捕获拆分,为后处理步骤。

参见Ruby 演示

def cmd_split(s)
    rx = /(?<command>[^<>\s]+)(<(?<args>(\d+)+(?:,\s*\d+)*)>)?/
    res = []
    s.scan(rx) { 
        res << ($~[:args] != nil ? 
            Hash["command", $~[:command], "args", $~[:args].split(/,\s*/)] : 
            Hash[$~[:command], ""]) }
    return res
end

puts cmd_split("print<1, 2, 3>") # => {"command"=>"print", "args"=>["1", "2", "3"]}
puts cmd_split("disp<1>")        # => {"command"=>"disp", "args"=>["1"]}
puts cmd_split("+")              # => {"+"=>""}
于 2016-11-08T22:08:57.420 回答