我正在编写一个脚本,将模板文件转换为胡子,我想使用Nokogiri。但是,有没有一种方法可以将它与胡子一起使用,特别是将<tmpl_if var>
等标签转换为{{#var}}
?本质上,我正在尝试转换:
<tmpl_if foo>
<tmpl_if bar>
<p>Test</p>
</tmpl_if>
</tmpl_if>
至
{{#foo}}
{{#bar}}
<p>Test</p>
{{/bar}}
{{/foo}}
我可以得到我需要更改的节点,但我找不到只更改开始和结束标记的方法。有没有什么方法可以在不影响内部HTML的情况下使用regex将标记更改为字符串?
您可以这样做:
-
使用nokogiri,可以更改每个tmpl_if标签的标签名称,如下所示:
<tmpl_if bar>
=><tmpl_if_bar bar>
。此更改的目标是将属性名称包含在结束标记中。 -
您用gsub替换所有
<tmpl_if_...>
标记。
-
require 'nokogiri'
html_doc = <<EOD
<tmpl_if foo>
<tmpl_if bar>
<p>Test</p>
</tmpl_if>
</tmpl_if>
EOD
doc = Nokogiri::HTML.parse(html_doc)
attrList = doc.xpath('//tmpl_if/@*')
attrList.each{|attr| attr.parent.name = attr.parent.name + "_" + attr.name}
html_doc = doc.css('body').inner_html
reps = [[/<tmpl_if_(w+)[^>]*>/, '{{#1}}'], [/</tmpl_if_(w+)>/, '{{/1}}']]
reps.each {|rep| html_doc.gsub!(rep[0], rep[1])}
puts html_doc
这样可以避免所有嵌套问题。
我找到了一种方法,首先找到每个需要更改的节点,然后将其转换为字符串,在替换节点之前使用regex进行替换(依赖\a和\Z)。如果反转列表,它将首先对内部节点进行操作;
@doc.css("tmpl_if").reverse.each do |node|
str = node.to_s;
str.sub(/A<tmpl_if ([^>]*)>(.*)</tmpl_if>Z/m, '{{#1}}2{{/1}}')
node.replace(str)
end
`
一些更改可以使这适用于任何/所有像这样的标记。A
表示字符串的开始,Z
表示结束(字符串,而不是行)。尽管考虑到列表已经从内到外运行,可能不需要它们,所以每个节点上应该只剩下一个开始和结束标记。