2016-08-20 63 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"