如何使用RubyGem Sanitize变换器将无序列表清理为逗号分隔列表?

任何熟悉RubyGem Sanitize的人都提供了构建“Transformer”进行转换的示例

"
  • a
  • b
  • c
"

 "a,b, and c" 

IMO变换器不是用于提取这样的数据:

变形金刚允许您使用自己的自定义逻辑过滤和修改节点[…]

这不是你想要做的; 你试图从节点中提取数据并对其进行转换。 在你的例子中,你没有对每个元素做同样的事情:你有时会附加一个逗号,有时会附加一个逗号和单词“and”。

为此,您需要保存状态和后处理,或者在节点流中向前看以查看您是否正在访问最后一个节点。 我不知道用Sanitize的变换器做一些简单的方法,所以这个例子保存了状态和后期处理。

 require 'sanitize' items = [] s = "
  • some space
  • more stuff with spaces
  • last one
" save_li = lambda do |env| node = env[:node] items << node.text.strip if node.text? end Sanitize.clean(s, :transformers => save_li) # => " some space more stuff with spaces last one " output = "#{items[0..-2].join(", ")}, and #{items[-1]}" # => "some space, more stuff with spaces, and last one"

IMO这个例子是对变形金刚的滥用,因为它只是为了它的副作用而运行,除了寻找文本节点之外什么也没做。

如果其中一个列表项嵌入了HTML,则天真的方法不再有效,并且您需要开始了解更多Nokogiri:

 items = [] s = "
  • some space
  • item with html
  • c
" save_li = lambda do |env| node = env[:node] items << node.content if node.name == "li" end Sanitize.clean(s, :transformers => save_li) # => " some space item with html c " output = "#{items[0..-2].join(", ")}, and #{items[-1]}" # => "some space, item with html, and c"

此方法依赖于未列入白名单的默认Sanitize行为。 save_li lambda仍然访问标签,但它们被剥离了。 这有可能在各种情况下引起问题。