2017-07-30 145 views
1

我有一个Apache2服务器端包含文件。它看起来像(节录实际数据):从文件读取变量并替换

<!--#set var="FIRST_VAR" value="HI" --> 
<!--#set var="SECOND_VAR" value"THERE" --> 
<!--#set var="FINAL_VAR" value="HEY/${FIRST_VAR}/${SECOND_VAR}/${FINAL_VAR}" --> 

我想要做的是做一个正则表达式匹配命名的变量,然后生成使用散,也许是嵌套的变量。例如:

@SSI["FIRST_VAR"] = "HI" 
@SSI["SECOND_VAR"] = "THERE" 
@SSI["FINAL_VAR"] = "HEY/HI/THERE" 

我不知道如何正确地做到这一点。

回答

2

假设你文件读入到一个字符串,字符串分隔成线,从带空白每行的结尾。

arr =<<_.lines.map(&:strip) 
<!--#set var="V1" value="HI" --> 
<!--#set var="V2" value="THERE" --> 
<!--#set var="FV" value="HEY/${V1}/${V2}" --> 
_ 
    #=> ["<!--#set var=\"V1\" value=\"HI\" -->", 
    # "<!--#set var=\"V2\" value=\"THERE\" -->", 
    # "<!--#set var=\"FV\" value=\"HEY/${V1}/${V2}\" -->"] 

我将使用以下正则表达式。

r1 =/
    (?<=\svar=\") # match ' var="' in a positive lookbehind 
    .+?    # match one or more characters lazily 
    (?=\")   # match '"' in a positive lookahead 
    /x    # free-spacing regex definition mode 

r2 =/
    (?<=\svalue=\") # match ' value"' in a positive lookbehind 
    .+?    # match one or more characters lazily 
    (?=\")   # match '"' in a positive lookahead 
    /x    # free-spacing regex definition mode 

r3 =/
    \/\$\{   # match '/${' 
    \w+    # match one or more word characters 
    \}    # match '}' 
    /x    # free-spacing regex definition mode 

r4 =/
    (?<=\/\$\{)  # match '/${' in a positive lookbehind 
    .+?    # match any number of character, lazily 
    (?=\})   # match `}` in a positive lookahead 
    /x    # free-spacing regex definition mode 

然后我们可以如下计算所需的返回值。

g = arr.each_with_object({}) do |s,h| 
    var = s[r1].strip 
    value = s[r2].strip 
    h["\/\$\{#{var}\}"] = value.gsub(r3) { |s| h.key?(s) ? "/#{h[s]}" : "" } 
end 
    #=> {"/${V1}"=>"HI", "/${V2}"=>"THERE", "/${FV}"=>"HEY/HI/THERE"} 

最后,修改密钥。

g.each_with_object({}) { |(k,v),h| h[k[r4]] = v } 
    #=> {"V1"=>"HI", "V2"=>"THERE", "FV"=>"HEY/HI/THERE"} 

上述两个表达式当然可以链接在一起。实际上,它可以写成一行,但我不会推荐它。

2

如果你有一个字符串等于文件的文本:

txt = <<-TXT 
<!--#set var="FIRST_VAR" value="HI" --> 
<!--#set var="SECOND_VAR" value="THERE" --> 
<!--#set var="FINAL_VAR" value="HEY/${FIRST_VAR}/${SECOND_VAR}/${FINAL_VAR}" --> 
TXT 

(也注意:我已经value后,在第二行添加了=

然后你就可以建立一个正则表达式像这样:

result = txt.scan /<!--#set var=\"(.+)\" value=\"(.+)\" -->/ 
# => 
# [["FIRST_VAR", "HI"], 
# ["SECOND_VAR", "THERE"], 
# ["FINAL_VAR", "HEY/${FIRST_VAR}/${SECOND_VAR}/${FINAL_VAR}"] 
# ] 

正则表达式基本上是包含在文件中的格式相同,除了报价都逃了出来,比赛组defin使用(.+)编辑。

虽然正则表达式可能是更好的,你也可以使用split采取更强力式的方法:

txt.split("\n").map do |line| 
    var, rest = line.split("var=\"")[1].split("\" value=\"") 
    value = rest.split("\"")[0] 
    [var, value] 
end 
+0

有趣的是这是多么干净。至少在我没有经验的头脑中。我可以到达那里,尽管我的方法不够干净。但是,我仍然不确定如何替换嵌入的变量引用,例如FIRST_VAR等以一种干净的方式。任何想法或提示? – farhany