两种选择:
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)+/
并在每次匹配重复时获取多个捕获。