如何在HTML标签边界上找到文本



我有这样的html:

<div>Lorem ipsum <b>dolor sit</b> amet.</div>

在此HTML中,如何找到针对搜索字符串ipsum dolor的基于纯文本的匹配?我需要匹配的启动和结束XPath节点指针,以及字符索引在这些启动和停止节点中指向。我使用Nokogiri与DOM一起使用,但是Ruby的任何解决方案都可以。

难度:

  • 我无法通过DOM进行node.traverse {|node| … },并且每当遇到文本节点时进行纯文本搜索,因为我的搜索字符串可以跨越标签边界。

  • 我将HTML转换为纯文本后无法进行纯文本搜索,因为我需要XPATH索引。

我可以通过基本的树遍历自己实施,但是在我询问是否有诺科吉里的功能或技巧更舒适。

您可以做类似:

的事情
doc.search('div').find{|div| div.text[/ipsum dolor/]}

最后,我们使用的代码如下。它显示了该问题中给出的示例,但也可以在任意深度HTML标签嵌套的通用情况下起作用。(这是我们需要的。)

此外,我们以一种可以忽略多余(≥2)个空格字符的方式实现了它。这就是为什么我们必须搜索比赛的结束,而不能仅使用搜索字符串/引用的长度以及匹配位置的开始:搜索字符串和搜索匹配中的Whitespace字符的数量可能有所不同。

doc = Nokogiri::HTML.fragment("<div>Lorem ipsum <b>dolor sit</b> amet.</div>")
quote = 'ipsum dolor'

# (1) Find search string in document text, "plain text in plain text".
quote_query = 
  quote.split(/[[:space:]]+/).map { |w| Regexp.quote(w) }.join('[[:space:]]+')
start_index = doc.text.index(/#{quote_query}/i)
end_index = start_index+doc.text[/#{quote_query}/i].size

# (2) Find XPath values and character indexes for our search match.
# 
# To do this, walk through all text nodes and count characters until 
# encountering both the start_index and end_index character counts 
# of our search match.
start_xpath, start_offset, end_xpath, end_offset = nil
i = 0
doc.xpath('.//text() | text()').each do |x|
  offset = 0
  x.text.split('').each do
    if i == start_index
      e = x.previous
      sum = 0
      while e
        sum+= e.text.size
        e = e.previous
      end
      start_xpath = x.path.gsub(/^?/, '').gsub(
        /#{Regexp.quote('/text()')}.*$/, ''
      )
      start_offset = offset+sum
    elsif i+1 == end_index
      e = x.previous
      sum = 0
      while e
        sum+= e.text.size
        e = e.previous
      end
      end_xpath = x.path.gsub(/^?/, '').gsub(
        /#{Regexp.quote('/text()')}.*$/, ''
      )
      end_offset = offset+1+sum
    end
    offset+=1
    i+=1
  end
end

在这一点上,我们可以在搜索匹配项的开始和停止中检索所需的XPATH值(此外,字符偏移了指向XPATH指定元素内部的确切字符的开始和搜索匹配匹配项的确切字符)。我们得到:

puts start_xpath
  /div
puts start_offset
  6
puts end_xpath
  /div/b
puts end_offset
  5

相关内容

  • 没有找到相关文章

最新更新