【问题标题】:Convert non-breaking spaces to spaces in Ruby将不间断空格转换为 Ruby 中的空格
【发布时间】:2011-02-05 01:06:52
【问题描述】:

我遇到的情况是,当编码为 utf-8 json 时,有时会使用\u00a0(不间断空格)而不是空格来发送来自 html 文本区域或输入的用户输入数据。

我认为这是 Firefox 中的一个错误,因为我知道用户不是故意放入不间断空格而不是空格。

Ruby 中还有两个 bug,其中一个可以用来对抗另一个。

无论出于何种原因,\s\u00a0 不匹配。

但是[^[:print:]],绝对不应该匹配)和\xC2\xA0 都将匹配,但我认为这些不是处理问题的理想方法。

还有其他解决此问题的建议吗?

【问题讨论】:

  • 哪个 Ruby 版本?在 1.9.2 /\u00a0/ 中匹配。
  • \s 不匹配 \u00a0 \u00a0 匹配 1.9,但我不确定 1.8
  • 规则#1:当你认为你在一个非常流行的程序中发现了一个错误,尤其是在一些经过测试和广泛使用的程序中,比如 Firefox 的 textarea 处理,非常安静和仔细地检查你的测试. 100 次中有 99 次问题都在你身边。当我看到文本字段中出现不间断空格时,人们可能会在其中粘贴文本,我怀疑是 Microsoft Word 或设置为替换   的编辑器。对于空间。您可以通过创建一个页面、在其中放置一个文本区域并尝试复制问题来轻松测试您的理论。

标签: ruby json unicode utf-8 whitespace


【解决方案1】:

使用/\u00a0/ 匹配不间断空格。例如s.gsub(/\u00a0/, ' ') 将所有不间断空格转换为常规空格。

使用/[[:space:]]/ 匹配所有空格,包括Unicode 空格,如不间断空格。这与 /\s/ 不同,后者仅匹配 ASCII 空格。

另请参阅:Ruby Regexp documentation

【讨论】:

  • unicode.org/versions/Unicode6.2.0/ch06.pdf - 空格字符。但 id 看起来确实不完整
  • 将我的答案修复为简单地使用[[:space]](自我注意:不是[:space])。
  • "s.gsub(/\u00a0/, ' ') " 是我一直在寻找的。​​span>
  • @JoLiss 您的答案是正确的,但是您的“自我说明”缺少尾随冒号。我自己也多次犯过同样的错误。
【解决方案2】:

如果您不能将 \s 用于 Unicode 空白,这是 Ruby 正则表达式实现中的一个错误,因为根据UTS#18 “Unicode Regular Expressions” Annex C on Compatibility Properties \s绝对需要匹配任何 Unicode 空白代码观点。

没有回旋余地,因为详细说明标准建议和 POSIX 兼容性的两列对于 \s 案例是相同的。您无法记录解决此问题的方法:如果您不这样做,您就违反了 Unicode 标准,尤其是 UTS#18 的 RL1.2a

如果您不符合 RL1.2a,则不符合 1 级要求,这是在 Unicode 上使用正则表达式所需的最基本和最基本的功能。没有它,你几乎迷路了。 这就是标准存在的原因。我记得 Ruby 也未能满足其他几个 1 级要求。因此,如果您确实需要使用正则表达式处理 Unicode,您可能希望使用至少满足 1 级的编程语言。

请注意,您不能使用像 \p{Zs} 这样的 Unicode 通用类别属性来代表 \p{Whitespace}。这是因为 Whitespace 属性是派生属性,而不是一般类别。其中还包含控制字符,而不仅仅是分隔符。

【讨论】:

    【解决方案3】:

    回答问题的实际功能 IRB 代码示例,带有最新的 Rubies(2012 年 5 月)

    红宝石 1.9

    require 'rubygems'
    require 'nokogiri'
    RUBY_DESCRIPTION # => "ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]"
    doc = '<html><body> &nbsp; </body></html>'
    page = Nokogiri::HTML(doc)
    s = page.inner_text
    s.each_codepoint {|c| print c, ' ' } #=> 32 160 32
    s.strip.each_codepoint {|c| print c, ' ' } #=> 160
    s.gsub(/\s+/,'').each_codepoint {|c| print c, ' ' } #=> 160
    s.gsub(/\u00A0/,'').strip.empty? #true
    

    红宝石 1.8

    require 'rubygems'
    require 'nokogiri'
    RUBY_DESCRIPTION # => "ruby 1.8.7 (2012-02-08 patchlevel 358) [x86_64-linux]"
    doc = '<html><body> &nbsp; </body></html>'
    page = Nokogiri::HTML(doc)
    s = page.inner_text # " \302\240 "
    s.gsub(/\s+/,'') # "\302\240"
    s.gsub(/\302\240/,'').strip.empty? #true
    

    【讨论】:

      【解决方案4】:

      无论出于何种原因,\s 都与 \u00a0 不匹配。

      我认为“不管是什么原因”都是不应该的。只有 POSIX 和 \p 构造字符类是 Unicode 感知的。字符类缩写不是:

      Sequence   As[...]        Meaning
           \d    [0-9]          ASCII decimal digit character
           \D    [^0-9]         Any character except a digit
           \h    [0-9a-fA-F]    Hexadecimal digit character
           \H    [^0-9a-fA-F]   Any character except a hex digit
           \s    [ \t\r\n\f]    ASCII whitespace character
           \S    [^ \t\r\n\f]   Any character except whitespace
           \w    [A-Za-z0-9\_]  ASCII word character
           \W    [^A-Za-z0-9\_] Any character except a word character
      

      【讨论】:

      • 哦,它是应该,好吧。它只是没有。看我的回答。
      • 它在规范中和在代码中是有区别的。它是否应该因为规范现在是一个有争议的问题,因为它不存在,无论我们多么希望它在那里,直到核心团队中的某个人决定添加它.所以,现实是,它不应该工作,因为它没有被编码。也许在未来的转速会改变。我希望看到它符合规格,但他们没有问我。
      • 这是一个非常奇怪的事情。 tchrist 是绝对正确的,并且说某些“不应该起作用”因为它目前不起作用是我一段时间以来读到的最好的空洞事实。无论哪种方式 - [[:space:]] 上的 gsub 直到有人让 Ruby 真正符合标准。
      【解决方案5】:

      对于旧版本的 ruby​​ (1.8.x),修复是问题中描述的。

      这已在 ruby​​ 1.9+ 的较新版本中得到修复。

      【讨论】:

      • 你能说得更具体些吗?我刚刚在 1.9.3p194 上遇到了同样的问题,这是相当 1.9ish。 \s 不匹配 unicode 不间断空格,但 \u00a0 匹配。
      【解决方案6】:

      虽然与 Ruby 无关(也与这个问题没有直接关系),但问题的核心可能Alt+Space on Macs 会产生一个不间断的空间。

      这可能会导致各种奇怪的行为(尤其是在终端中)。

      对于那些对更多细节感兴趣的人,我前段时间写了关于这个话题的“Why chaining commands with pipes in Mac OS X does not always work”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多