用ruby读取多行字符串,用“\”打破

时间:2017-02-19 16:02:01

标签: ruby file parsing

在某些RPM规范文件中(例如),有多行字符串,如下所示:

%build
export CFLAGS="%{optflags} -fomit-frame-pointer \
-W -Wall -Wno-unused-parameter -Wstrict-prototypes -Wpointer-arith -fPIE"
export LDFLAGS="-pie"
%configure --disable-silent-rules \
  gl_cv_func_printf_directive_n=yes \
  gl_cv_func_printf_infinite_long_double=yes

如果我试图使用以下代码片段解析此文件:

if = File.open("foo.spec")

f.each do |line|
  puts line if line =~ /CFLAGS/m
end

该行将打印不完整。 <-W -Wall ... -fPIE“将不会打印出来。

有什么办法可以抓住它吗?

2 个答案:

答案 0 :(得分:2)

您正在逐行阅读ruby文件。由于它是纯文本,因此结果为正确。但是,如果要将命令行保持在一起,则需要将它们连接起来。您可以使用正则表达式解析整个文本,而不是在每一行上进行迭代:

file = File.open("foo.spec")
# Read the file's content as a string.
content = file.read

# Split the content by lines
raw_lines = content.split /\r?\n/

# Iterate each line
lines = raw_lines.inject([]) do |acc, line|
  # Add to the last if the previous lines ends with a \ character
  if acc[-1].to_s =~ /\\\s*$/
    acc[-1] += line
    acc
  # Otherwise, register it as a new line
  else
    acc << line
  end
end

# The result will be an array with all your lines.
lines.each do |line|
  puts line if line =~ /CFLAGS/m
end

# Don't forget to close the file stream!
file.close

如果您要删除多行行之间的/字符以将其转换为一行,则需要替换它们:

line.gsub! "\\", ' '    # Replace multi-lines characters

答案 1 :(得分:1)

我发现上面的示例似乎会删掉每一行的最后一个字符,所以这是另一种选择:

IO.read("foo.spec").split(/(?<!\\)\n/).select{|x| x =~ /CFLAGS/ }