我有这样一个字符串:
"Energia Elétrica kWh<span class=\"_ _3\"> </span> 10.942 <span class=\"_ _4\"> </span> 0,74999294 <span class=\"_ _5\"> </span> 8.206,39"
我想通过它的 HTML 标签拆分它,这些标签总是 <span>
.我试过类似的东西:
my_string.split(/<span(.*)span>/)
但是没有成功,只正确匹配了第一个元素。
有人知道我的正则表达式有什么问题吗?在这个例子中,我期望返回值是:
["Energia Elétrica kWh", "10.942", "0,74999294" ,"8.206,39"]
我想要类似 strip_tags
的东西,但不是返回经过清理的字符串,而是通过删除的标签拆分数组。
最佳答案
不要使用模式来操纵 HTML。这是一个path destined to make you insane .
改为使用 HTML 解析器。 Ruby 的标准是 Nokogiri :
require 'nokogiri'
doc = Nokogiri::HTML::DocumentFragment.parse("Energia Elétrica kWh<span class=\"_ _3\"> </span> 10.942 <span class=\"_ _4\"> </span> 0,74999294 <span class=\"_ _5\"> </span> 8.206,39")
您可以使用 text
来提取所有文本,但是,如果您要的是结构化数据,那么通常很难提取字段,因为文本节点可以连接起来导致运行-关于文字,所以要小心:
doc.text # => "Energia Elétrica kWh 10.942 0,74999294 8.206,39"
相反,我们通常从单个节点中提取数据:
doc.search('span')[1].next_sibling.text # => " 0,74999294 "
doc.search('span').last.next_sibling.text # => " 8.206,39"
或者,我们遍历节点,然后使用 map
获取节点的文本:
doc.search('span').map{ |span| span.next_sibling.text.strip }
# => ["10.942", "0,74999294", "8.206,39"]
我会这样解决问题:
data = [doc.at('span').previous_sibling.text.strip] # => ["Energia Elétrica kWh"]
data += doc.search('span').map{ |span| span.next_sibling.text.strip }
# => ["Energia Elétrica kWh", "10.942", "0,74999294", "8.206,39"]
或者:
spans = doc.search('span')
data = [
spans.first.previous_sibling.text,
*spans.map{ |span| span.next_sibling.text }
].map(&:strip)
# => ["Energia Elétrica kWh", "10.942", "0,74999294", "8.206,39"]
虽然正则表达式通常可以在初始尝试时起作用,但 HTML 格式的更改可能会破坏模式,强制进行额外的更改,然后进行另一个更改,然后再进行另一个更改,直到模式过于复杂为止,而正确编写的解析器方法通常非常有弹性并且不会出现问题。
关于ruby - 如何使用正则表达式按 HTML 标签拆分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39923099/