使用Nokogiri小胡子?

时间:2014-09-22 22:02:44

标签: html ruby regex nokogiri

我正在编写一个脚本来将模板文件转换为小胡子,我想使用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?

2 个答案:

答案 0 :(得分:0)

您可以这样做:

  • 使用nokogiri,您可以更改每个tmpl_if标记的标记名称:<tmpl_if bar> =&gt; <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

这样可以避免所有嵌套问题。

答案 1 :(得分:0)

我找到了一种方法,首先找到需要更改的每个节点,然后将其转换为字符串,在替换节点之前使用正则表达式进行替换(依赖于\ 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表示结束(字符串,而不是行)。虽然它们可能不需要考虑列表已经在内部运行到外部,但每个节点上应该只剩下一个开始和结束标记。