红宝石中的多线正则表达式

时间:2018-04-29 11:22:41

标签: ruby regex

我想从文件中提取两个关键字(<< -DOC,DOC)之间的所有文本。 例如,如果我的文件内容如下

abc.rb

def abc
    <<-DOC abc:
        return "hahaha"
    DOC
    puts "hahaha"
end

def efg
    <<-DOC efg:
        return "hehehe"
    DOC
    puts "hehehe"
end

我想得到两场比赛:

<<-DOC abc:
    return "hahaha"
DOC

<<-DOC efg:
    return "hehehe"
DOC

我试过File.read("abc.rb").match(/<<-DOC(.*?)DOC/m) 但它给出了第一次出现<<-DOC(内部abc)和最后一次出现DOC(内部制造)之间的所有文本

2 个答案:

答案 0 :(得分:2)

据我所知,你的正则表达式是正确的,(。*?)应该是非贪婪的匹配。我认为你遇到的问题是Ruby中的while( box[0] < box[2]): y_axis = int(box[1]) while(y_axis < box[3]): heatmap[box[0]][y_axis] += 1 y_axis = y_axis+1 box[0] = box[0]+1 只返回正则表达式的第一个匹配。例如

match

您真正想要使用的是File.read("abc.rb").match(/<<-DOC(.*?)DOC/m) => #<MatchData "<<-DOC abc:\n return \"hahaha\"\n DOC" 1:" abc:\n return \"hahaha\"\n ">

scan

这将返回一个数组数组,每个数组包含正则表达式中捕获的组。见https://ruby-doc.org/core-2.2.0/String.html#method-i-scan

答案 1 :(得分:2)

Flip-flop解决方案:

File.readlines("abc.rb").select do |line|
  true if (line.include? '<<-DOC')...(line.include? 'DOC')
end
#⇒ [
#     [0] "    <<-DOC abc:",
#     [1] "        return \"hahaha\"",
#     [2] "    DOC",
#     [3] "    <<-DOC efg:",
#     [4] "        return \"hehehe\"",
#     [5] "    DOC"
# ]