【问题标题】:I can't remove whitespaces from a string parsed by Nokogiri我无法从 Nokogiri 解析的字符串中删除空格
【发布时间】:2012-12-17 03:22:56
【问题描述】:

我无法从字符串中删除空格。

我的 HTML 是:

<p class='your-price'>
Cena pro Vás: <strong>139&nbsp;<small>Kč</small></strong>
</p>

我的代码是:

#encoding: utf-8
require 'rubygems'
require 'mechanize'

agent = Mechanize.new
site  = agent.get("http://www.astratex.cz/podlozky-pod-raminka/doplnky")
price = site.search("//p[@class='your-price']/strong/text()")

val = price.first.text  => "139 "
val.strip               => "139 "
val.gsub(" ", "")       => "139 "

gsubstrip 等不起作用。为什么,以及如何解决这个问题?

val.class      => String
val.dump       => "\"139\\u{a0}\""      !
val.encoding   => #<Encoding:UTF-8>

__ENCODING__               => #<Encoding:UTF-8>
Encoding.default_external  => #<Encoding:UTF-8>

我使用的是 Ruby 1.9.3,所以 Unicode 应该不是问题。

【问题讨论】:

  • 提示:您可以使用 val = site.at('p.your-price &gt; strong').text 代替 XPath。
  • 是的,但 CSS 不是我的菜。 :)

标签: ruby nokogiri whitespace mechanize mechanize-ruby


【解决方案1】:

strip 仅删除 ASCII 空格,而您在此处获得的字符是 Unicode 不间断空格。

删除角色很容易。您可以通过提供带有字符代码的正则表达式来使用gsub

gsub(/\u00a0/, '')

你也可以调用

gsub(/[[:space:]]/, '')

删除所有 Unicode 空格。详情请查看Regexp documentation

【讨论】:

  • 如果您愿意,也可以使用\p{Space} 作为[[:space:]] 的替代品(我认为它们是相同的)。
  • 另一种方法是在解析之前使用gsub('&amp;nbsp;', '')gsub('&amp;nbsp;', ' ') 并一次性获取它们。
  • @A.D. /\s/ 也是纯 ASCII 码
  • "Programmers like me assume that Ruby will care about this automatically" 不要假设,要自学你的语言是做什么的。如果语言包罗万象,那么在我们需要它来做一些不同或新的事情的时候,它就毫无价值了。作为程序员,我们从设计为通用工具的小段代码中设计解决方案。我们将它们插入,使用它们将数据塑造成我们需要的任何东西,我们不会盲目地“假设”事情会神奇地工作。只要互联网上充斥着 HTML,ASCII 与 UTF-8/Unicode 将是一场未来几年的战斗。
  • 我同意程序员不能假设一切,但是Class: String 说:“A String object holds and manipulates an arbitrary sequence of bytes, typically representing characters.”当文档说“Removes leading and trailing whitespace from str.”时,我认为它会删除所有空格。我必须深入挖掘,也许是为了另一个问题。
【解决方案2】:

如果我想删除不间断空格 "\u00A0" AKA &amp;nbsp; 我会这样做:

require 'nokogiri'

doc = Nokogiri::HTML("&nbsp;")

s = doc.text # => " "

# s is the NBSP
s.ord.to_s(16)                   # => "a0"

# and here's the translate changing the NBSP to a SPACE
s.tr("\u00A0", ' ').ord.to_s(16) # => "20"

所以tr("\u00A0", ' ') 将您带到您想去的地方,此时,NBSP 现在是一个空间:

tr 非常快速且易于使用。

另一种方法是在从 HTML 中提取实际编码字符“&amp;nbsp;”之前对其进行预处理。这是简化的,但它适用于整个 HTML 文件以及字符串中的单个实体:

s = "&nbsp;"

s.gsub('&nbsp;', ' ') # => " "

对目标使用固定字符串比使用正则表达式更快:

s = "&nbsp;" * 10000

require 'fruity'

compare do
  fixed { s.gsub('&nbsp;', ' ') }
  regex { s.gsub(/&nbsp;/, ' ') }
 end

# >> Running each test 4 times. Test will take about 1 second.
# >> fixed is faster than regex by 2x ± 0.1

如果您需要正则表达式的功能,它们很有用,但它们会大大降低代码速度。

【讨论】:

    猜你喜欢
    • 2015-09-22
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    相关资源
    最近更新 更多