Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 将HTML字符串解析为数组_Ruby_Nokogiri_Diff Lcs - Fatal编程技术网

Ruby 将HTML字符串解析为数组

Ruby 将HTML字符串解析为数组,ruby,nokogiri,diff-lcs,Ruby,Nokogiri,Diff Lcs,我正在为TinyMCE生成的HTML主体开发类似wiki的差异功能diff-lcs是一种接受数组或对象的差异gem。大多数差异任务都在代码上,只是比较行。HTML文本体之间的差异更为复杂。如果我只是插入正文,我会得到一个字符一个字符的比较。虽然输出是正确的,但看起来像垃圾 seq1 = "<p>Here is a paragraph. A sentence with <strong>bold text</strong>.</p><p>T

我正在为TinyMCE生成的HTML主体开发类似wiki的差异功能
diff-lcs
是一种接受数组或对象的差异gem。大多数差异任务都在代码上,只是比较行。HTML文本体之间的差异更为复杂。如果我只是插入正文,我会得到一个字符一个字符的比较。虽然输出是正确的,但看起来像垃圾

seq1 = "<p>Here is a paragraph. A sentence with <strong>bold text</strong>.</p><p>The second paragraph.</p>"

seq2 = seq1.gsub(/[.!?]/, '\0|').split('|')
=> ["<p>Here is a paragraph.", " A sentence with <strong>bold text</strong>.", "</p><p>The second paragraph.", "</p>"]

我发现了很多简洁的Nokogiri方法,但我发现没有任何方法能做到上述任何一点。

您没有用惯用的Ruby编写代码。我们在变量名中不使用混合的大小写,同样,在一般编程中,为了清晰起见,最好使用助记变量名。重构代码,使其更符合我的编写方式:

tags = %w[p ol ul li h6 h5 h4 h3 h2 h1 em strong i b table thead tbody th tr td]
# Deconstruct HTML body 1
doc = Nokogiri::HTML.fragment(@versionOne.body)
nodes = doc.css(tags.join(', '))

# Reconstruct HTML body 1 into comparable array
output = []
nodes.each do |node|

  output << [
    "<#{ node.name }",
    node.attributes.map { |param| '%s="%s"' % [param.name, param.value] }.join(' '),
    '>'
  ].join

  output << node.children.to_s.gsub(/[\s.!?]/, '|\0|').split('|').flatten

  output << "</#{ node.name }>"

end

# Same deal for nokoOutput2

sdiff = Diff::LCS.sdiff(nokoOutput2.flatten, output.flatten)
在您的代码中根本不是Ruby,因为字符串没有
运算符。您是否在代码中添加了
|
运算符,但未显示该定义

我看到的一个问题是:

output << node.children.to_s.gsub(/[\s.!?]/, '|\0|').split('|').flatten
可能会提高你的产量。这是未经测试的,但总体思路如下:

def dump_node(node)

  output = [
    "<#{ node.name }",
    node.attributes.map { |param| '%s="%s"' % [param.name, param.value] }.join(' '),
    '>'
  ].join

  output += node.children.map{ |n| dump_node(n) }

  output << "</#{ node.name }>"

end
def dump_节点(节点)
输出=[

“您没有使用惯用的Ruby编写代码。我们不会在变量名中使用大小写混合格式。此外,在编程中,为了清晰起见,通常使用助记变量名是一个好主意。重构您的代码,使其更符合我的编写方式:

tags = %w[p ol ul li h6 h5 h4 h3 h2 h1 em strong i b table thead tbody th tr td]
# Deconstruct HTML body 1
doc = Nokogiri::HTML.fragment(@versionOne.body)
nodes = doc.css(tags.join(', '))

# Reconstruct HTML body 1 into comparable array
output = []
nodes.each do |node|

  output << [
    "<#{ node.name }",
    node.attributes.map { |param| '%s="%s"' % [param.name, param.value] }.join(' '),
    '>'
  ].join

  output << node.children.to_s.gsub(/[\s.!?]/, '|\0|').split('|').flatten

  output << "</#{ node.name }>"

end

# Same deal for nokoOutput2

sdiff = Diff::LCS.sdiff(nokoOutput2.flatten, output.flatten)
在您的代码中根本不是Ruby,因为字符串没有
运算符。您是否将
运算符添加到代码中,但没有显示该定义

我看到的一个问题是:

output << node.children.to_s.gsub(/[\s.!?]/, '|\0|').split('|').flatten
可能会提高您的输出。这是未经测试的,但总体思路是:

def dump_node(node)

  output = [
    "<#{ node.name }",
    node.attributes.map { |param| '%s="%s"' % [param.name, param.value] }.join(' '),
    '>'
  ].join

  output += node.children.map{ |n| dump_node(n) }

  output << "</#{ node.name }>"

end
def dump_节点(节点)
输出=[

“以下是您如何使用

需要“nokogiri”
html=“这里是一个段落。第二段是一个带有粗体文本的句子。

” 类ArraySplitParserdef end_元素(名称);@array以下是使用

需要“nokogiri”
html=“这里是一个段落。第二段是一个带有粗体文本的句子。

” 类ArraySplitParser
def end_元素(名称);@array Nokogiri设计用于解析XML/HTML,因此字符串数组
seq2
的起点不是Nokogiri的恰当用法。TinyMCE的完整输出是什么?是否有根元素?TinyMCE的输出类似于seq1。seq2不重要,我只想使用类似于seq3的格式。它看起来我必须为孩子们解析Nokogiri对象,然后执行类似于seq2的操作。你可以使用SAX接口将每个标记附加到数组中,对于文本节点,按单词拆分。我不熟悉SAX,你能详细说明一下吗?你的HTML文件有多大?DOM解析,这是使用Nokogiri解析HTML的实际方法,非常简单r、 好处是整个文件都被解析并存储在内存中,这样你就可以重新构造HTML,或者在其中跳转。缺点是它都存储在内存中。我很少看到一个HTML文件不能存储在内存中,否则它也不能存储在浏览器中。SAX只允许线性处理标记,但不能将它拉到内存中,如此大的文件,不是吗典型的XML是可以处理的。有关更多信息,请参阅。Nokogiri设计用于解析XML/HTML,因此字符串数组
seq2
的起点不适合使用Nokogiri。TinyMCE的完整输出是什么?是否有根元素?TinyMCE的输出类似于seq1。seq2不重要,我只是不喜欢o使用类似于seq3的格式。看起来我必须为孩子们解析Nokogiri对象,然后执行类似于seq2的操作。你可以使用SAX接口将每个标记附加到数组中,对于文本节点,按单词拆分。我不熟悉SAX,你能详细说明一下吗?你的HTML文件有多大?DOM解析,实际上是使用Nokogiri解析HTML的方法要简单得多。好处是整个文件都被解析并保存在内存中,这样你就可以重新构造HTML,或者在其中跳转。缺点是它都保存在内存中。我很少看到一个HTML文件不能保存在内存中,否则它也不能保存在浏览器中。SAX只允许对标记进行线性处理,而不是t不会将其拉入内存,因此可以处理大量文件,通常是XML。有关更多信息,请参阅。谢谢!知道这些非常好。我认为@maerics answer与sax解析器一起使用可以避免递归转储节点的需要吗?sax本质上是串行查看每个标记,这有助于以相同的方式输出节点。作为因此,出于这个目的,它避免了递归转储节点的需要。请参阅我对原始问题关于SAX与DOM的优缺点的评论。谢谢!知道这些都很好。我认为@maerics answer与SAX解析器一起避免递归转储节点的需要对吗?SAX本质上是串行地查看每个标记,这会导致它本身以相同的方式输出节点。因此,它避免了递归转储节点的需要。请参阅我对SAX与DOM的优缺点的原始问题的评论。有什么想法可以添加到
ArraySplitParser
以保留标记属性吗?@Archonic提示:查看
start\e的参数lement
方法。解析器传入一个
attrs
变量。我已经更新了答案。它正在解析attrs,但没有将它们写入
@array
。我回来了。你知道如何处理这个方法中的图像吗?你知道我可以向
ArraySplitParser
添加什么来保留标记属性吗?@Archonic提示:看看参数到
start\u元素
方法。Th
def dump_node(node)

  output = [
    "<#{ node.name }",
    node.attributes.map { |param| '%s="%s"' % [param.name, param.value] }.join(' '),
    '>'
  ].join

  output += node.children.map{ |n| dump_node(n) }

  output << "</#{ node.name }>"

end