【问题标题】:Nokogiri substituting text between tagsNokogiri 在标签之间替换文本
【发布时间】:2021-07-21 11:19:28
【问题描述】:

我试图在执行正则表达式操作时区分纯字符串文本和有效的 HTML 标记。

我的初始实现:

def html_parser(body, terms:)
  doc = Nokogiri::HTML(body)
  terms.each do |term|
    doc.xpath('//text()').each do |node|
      dummy = node.add_previous_sibling(Nokogiri::XML::Node.new('dummy', doc))
      dummy.add_previous_sibling(Nokogiri::XML::Text.new(node.to_s.gsub(/\b#{term}\b/, process_term(term)), doc))
      node.remove
      dummy.remove
    end
  end

  doc.at_css('body').children.to_html.gsub('&lt;', '<').gsub('&gt;', '>').gsub('&amp;lt;', '<').gsub('&amp;gt;', '>')
end

html_parser('hello world', terms: ['hello'])
# After performing the operation, the `doc` is wrapping the string inside the `p` tag automatically, which I do not want.
=> '<p>hello world</p>' # this would be some other value, main problem is wrapping with `p` tag.

但是,这对于其他有效的 HTML 标记也很有效。

string = '<span>hello world<span>'
html_parser(string, terms: ['hello'])
# works fine

【问题讨论】:

    标签: ruby-on-rails ruby nokogiri


    【解决方案1】:

    通过使用Nokogiri::Document(),您是在要求 Nokogiri 根据您传入的内容创建 HTML 文档的表示。如果您传入的不是完整的 HTML 文档,而是像这里这样的片段, Nokogiri 将您的输入文本包装到它自己的模板中——如果您没有任何外部标签,它将添加&lt;p&gt; 元素。您可以通过在文档上调用#to_s 来查看:

    Nokogiri::HTML('Hello world').to_s
    
    # => <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n" +
    "<html><body><p>Hello world</p></body></html>"
    

    您可以尝试寻找方法让 Nokogiri 使用更好的模板构造,但实际上我想说您可以通过以下两种方法之一更快地获得您想要的东西:

    1. 考虑使用文档片段(例如,Nokogiri::HTML.fragment(body))是否能满足您的需求。这可能需要对您的代码进行更大规模的重构,但最终得到的结果可能会更整洁、更易于维护。
    2. 您可以通过将方法的 body 输入包装到您自己的 HTML 文档模板中来快速取胜,因此 Nokogiri 不会为您执行此操作。例如:
    def html_parser(body, terms:)
      html = "<html><body>#{body}</body></html>"
      doc = Nokogiri::HTML(html)
      # etc.
    

    后一个选项会更快地解决您的问题,但代码可能不那么整洁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多