两种选择:
s = "[test| blah] \n [foo |bar bar bar]\n[test| abc |123 | 456 789]"
s.split(/\s*\n\s*/).map{ |p| p.scan(/[^|\[\]]+/).map(&:strip) }
#=> [["test", "blah"], ["foo", "bar bar bar"], ["test", "abc", "123", "456 789"]]
irb> s.split(/\s*\n\s*/).map do |line|
line.sub(/^\s*\[\s*/,'').sub(/\s*\]\s*$/,'').split(/\s*\|\s*/)
end
#=> [["test", "blah"], ["foo", "bar bar bar"], ["test", "abc", "123", "456 789"]]
它们都从换行符开始(丢弃周围的空白)。
然后第一个通过查找不是 , 或的任何内容来拆分每个块,[然后|丢弃]额外的空格(调用strip每个)。
然后第二个丢弃前导[和尾随](带有空格),然后拆分|(带有空格)。
您无法使用单个scan. 关于你能得到的最接近的是:
s.scan /\[(?:([^|\]]+)\|)*([^|\]]+)\]/
#=> [["test", " blah"], ["foo ", "bar bar bar"], ["123 ", " 456 789"]]
…丢弃信息,或者这个:
s.scan /\[((?:[^|\]]+\|)*[^|\]]+)\]/
#=> [["test| blah"], ["foo |bar bar bar"], ["test| abc |123 | 456 789"]]
…将每个“数组”的内容捕获为单个捕获,或者这样:
s.scan /\[(?:([^|\]]+)\|)?(?:([^|\]]+)\|)?(?:([^|\]]+)\|)?([^|\]]+)\]/
#=> [["test", nil, nil, " blah"], ["foo ", nil, nil, "bar bar bar"], ["test", " abc ", "123 ", " 456 789"]]
…硬编码为最多四个项目,并插入nil您需要删除的条目.compact。
没有办法使用 Rubyscan来获取类似的正则表达式/(?:(aaa)b)+/并在每次匹配重复时获取多个捕获。