2016-08-20 67 views
0

想象以后我有2个文件:红宝石返回文本(.txt)文件中的内容替换变量

A.txt 

This is a sentence with a #{variable}. 

和Ruby脚本。

Iamascript.rb 

... 
variable = "period" 
... 

有没有什么办法可以读取.txt文件的内容并在put'ing之前插入变量? 这种运行RB-脚本应

This is a sentence with a period. 

.txt文件是动态的,当我的意思输出。

回答

2

你正在寻找的是俗称模板什么,你已经基本定义的模板语言。红宝石居然附带了一个名为ERb的标准库模板语言,所以,如果你愿意改变你的模板语言的语法一点,你可以使用,而不是具有发明自己:

A.TXT

This is a sentence with a <%=variable%>. 

Iamascript。rb

require 'erb' 

variable = 'period' 

puts ERB.new(File.read('A.txt')).result(binding) 
# This is a sentence with a period. 
+0

谢谢你,这对我来说就像是一种魅力。是否也可以从外部.txt或.rb文件中读取散列,并在“主”代码中使用它的键(和值)? – Phero

+0

如果你想读取没有任何行为的纯数据,那么使用纯数据描述语言(而不是编程语言)要好得多(既简单又安全)。 (毕竟,ERb允许您嵌入*任意* Ruby代码,包括但不限于删除所有数据,格式化硬盘,启动后门等的代码)。如果您只想读取数据,使用XML,YAML或JSON等数据语言。 (我更喜欢JSON或YAML,而不是XML,取决于观众,即需要编辑该文件的人。) –

+0

该项目不是纯粹的数据提取,使用模板只是一个方便的例子。我只是想为一些代码段使用模板来创建多个(不同的)输出,而不必重新编码所有内容。但如果你说这是一个安全问题,我宁愿每次都更改我的代码。 – Phero

0

有一个“明显”(但很糟糕)的解决方案,这将是eval。 eval运行你给它的代码位。

这是安全问题的一个问题,但如果您需要的话,如果您需要在#{...}中使用复杂表达式,则可能是您正在寻找的问题。

如果您关心安全性,更正确的方法是使用Ruby的格式化运算符:%(与Python类似)。

template = "the variable's value is %{var}" 
puts template % {var: "some value"} => prints "the variable's value is some value" 
0

假设文件"A.txt"包含文本的一行(或该线从该文件中提取):

s1 = 'This is a sentence with a #{my_var}' 

和第二文件,"Iamascript.rb",包含:

s2 =<<_ 
line of code 
    line of code 
    my_var = "period" 
    line of code 
line of code 
_ 
    #=> "line of code\n line of code\n my_var = 'period'\n line of code\nline of code\n" 

让我们创建这些文件:

File.write("A.txt", s1) 
    #=> 35 
File.write("Iamascript.rb", s2) 
    #=> 78 

现在阅读"A.txt"的第一行,并提取字符串开头"\#{"和结尾"}",然后从该字符串中提取变量名称。

r1 =/
    \#\{ # match characters 
    [_a-z]+ # match > 0 understores or lower case letters 
    \}  # match character 
    /x  # free-spacing regex definition mode 

s1 = File.read("A.txt") 
    #=> "This is a sentence with a #{my_var}" 
match = s1[r1] 
    #=> "\#{my_var}" 
var_name = match[2..-2] 
    #=> "my_var" 

现在阅读“Iamascript.rb”并寻找与下面的正则表达式匹配的行。

r2 =/
    \A   # match beginning of string 
    #{var_name} # value of var_name 
    \s*=\s*  # match '=' and surrounding whitespace 
    ([\"'])  # match a single or double quote in capture group 1 
    ([^\"']+) # match other than single or double quote in capture group 2 
    ([\"'])  # match a single or double quote in capture group 3 
    \z   # match end of string 
    /x   # free-spacing regex definition mode 
#=>/
# \A   # match beginning of string 
# my_var  # value of var_name 
# \s*=\s*  # match '=' and surrounding whitespace 
# ([\"'])  # match a single or double quote in capture group 1 
# ([^\"']+) # match other than single or double quote in capture group 2 
# ([\"'])  # match a single or double quote in capture group 3 
# \z   # match end of string 
# /x 

如果发现匹配从"A.txt"返回符合文本替换,否则返回nil

if File.foreach("Iamascript.rb").find { |line| line.strip =~ r2 && $1==$3 } 
    str.sub(match, $2)  
else 
    nil 
end 
    #=> "This is a sentence with a period"