【问题标题】:What's the opposite of chr() in Ruby?Ruby 中 chr() 的反义词是什么?
【发布时间】:2010-09-23 10:50:28
【问题描述】:

在许多语言中,有一对函数chr()ord(),它们可以在数字和字符值之间进行转换。在某些语言中,ord() 称为asc()

Ruby 有 Integer#chr,效果很好:

>> 65.chr
A

很公平。但是你怎么走另一条路?

"A".each_byte do |byte|
   puts byte
end

打印:

65

这与我想要的非常接近。但我真的宁愿避免循环——我正在寻找足够短的东西,以便在声明 const 时可读。

【问题讨论】:

    标签: ruby ascii


    【解决方案1】:

    我正在为 1.8.6 和 1.9.3 编写代码,但我无法让这些解决方案在这两种环境中工作:(

    但是,我遇到了另一种解决方案: http://smajnr.net/2009/12/ruby-1-8-nomethoderror-undefined-method-ord-for-string.html

    这对我也不起作用,但我对其进行了调整以供我使用:

    unless "".respond_to?(:ord)
      class Fixnum
        def ord
          return self
        end
      end
    end

    完成后,以下内容将适用于两种环境

    'A'[0].ord

    【讨论】:

    • 当 user18096 写出他们的答案 "A".unpack("C")[0],那是针对 Ruby 1.8.1、Ruby 1.8.7 和 Ruby 1.9.2。它在您的环境中失败了吗?什么样的失败?
    • 嗨 RJHunter,我正在尝试将字符串中的特定字符转换为其数值。以下代码适用于 1.9.3 但不适用于 1.8.6。 self.status = tagAccountString[4].unpack('C')[0] 在 1.8.6 中,我得到 Exception undefined method unpack' for 0:Fixnum processing main buffered tag data - exit` 以下代码在两种环境中都有效(使用我提出的解决方案)self.status = tagAccountString[4].ord 任何建议(例如更好的解决方案)非常受欢迎
    • tagAccountString[4] 在较新的 Ruby 中返回一个字符串,但在 Ruby 1.8 中用于返回一个 Fixnum。这就是您看到错误undefined method unpack for 0:Fixnum 的原因。如果您总是想忽略四个字符并转换下一个字符,您可以使用status = tagAccountString[4,1].unpack('C')[0] 甚至status, = tagAccountString.unpack('xxxxC')
    • 感谢 RJHunter 的解释和替代解决方案。但是,由于“我的”解决方案更具可读性和可重用性,我会坚持下去(除非有充分的理由不这样做?)
    【解决方案2】:

    如果您不介意从数组中提取值,可以使用"A".bytes

    【讨论】:

      【解决方案3】:

      刚刚通过 RFC 组合纯 Ruby 版本的 Stringprep 时遇到了这个问题。

      注意chr 在 [0,255] 之外失败,请改用 1.9.x - 2.1.x 便携式替代品:

      [22] pry(main)> "\u0221".ord.chr
      RangeError: 545 out of char range
      from (pry):2:in 'chr'
      [23] pry(main)> x = "\u0221".unpack('U')[0]
      => 545
      [24] pry(main)> [x].pack('U')
      => "ȡ"
      [25] pry(main)>
      

      【讨论】:

      • 谢谢,这似乎是唯一给出char 的答案,并且在 unicode 的情况下它是正确的
      【解决方案4】:

      你可以拥有这些:

      65.chr.ord
      'a'.ord.chr
      

      【讨论】:

        【解决方案5】:

        如果 String#ord 在 1.9 中不存在,则在 2.0 中存在:

        "A".ord #=> 65
        

        【讨论】:

          【解决方案6】:

          我想 +1 dylanfm 和 AShelly 的评论,但添加 [0]:

          'A'.unpack('C')[0]

          unpack 调用返回一个包含单个整数的数组,在需要整数的地方并不总是接受它:

          $ ruby​​ -e 'printf("0x%02X\n", "A".unpack("C"))' -e:1:in `printf': 无法将 Array 转换为 Integer (TypeError) 从 -e:1 $ ruby​​ -e 'printf("0x%02X\n", "A".unpack("C")[0])' 0x41 $

          我正在尝试编写适用于 Ruby 1.8.1、1.8.7 和 1.9.2 的代码。

          编辑传递 C 以大写形式解包,因为 unpack("c") 给我 -1 而 ord() 给我 255(尽管在 C 的 char 签名的平台上运行)。

          【讨论】:

            【解决方案7】:

            在 Ruby 直到 1.8 系列(包括 1.8 系列)中,以下都将产生 65(对于 ASCII):

            puts ?A
            'A'[0]
            

            Ruby 1.9 中的行为发生了变化,以上两个都将产生“A”。在 Ruby 1.9 中执行此操作的正确方法是:

            'A'[0].ord
            

            不幸的是,ord 方法在 Ruby 1.8 中不存在。

            【讨论】:

            • 不幸的是,Ruby 1.9 中的“正确”方式如此之长,但至少在搜索“ord”时会更容易显示。感谢您非常详细的回答。
            【解决方案8】:

            另外,如果你在字符串中有字符并且你想在没有循环的情况下对其进行解码:

            puts 'Az'[0]
            => 65
            puts 'Az'[1]
            => 122
            

            【讨论】:

              【解决方案9】:

              试试:

              'A'.unpack('c')
              

              【讨论】:

              • 现在 Ruby 1.9 改变了 'A'[0] 的含义,这是更便携的方法。
              【解决方案10】:

              怎么样

              放?A

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-01-04
                • 2014-04-24
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2023-03-07
                相关资源
                最近更新 更多