试图理解Ruby .chr和.ord方法

时间:2016-06-14 19:49:56

标签: ruby encoding

我最近一直在使用Ruby chrord方法,有些事情我不明白。

我当前的项目涉及将单个字符转换为序数值。据我所知,如果我有一个字符串,其中包含一个单独的字符,如“A”,我在其上调用ord,我在ASCII表上的位置是65.调用反向,65.chr给出我是字符值“A”,所以这告诉我Ruby有一个有序字符值的集合,它可以使用这个集合给我一个特定字符的位置,或特定位置的字符。我可能错了,请纠正我,如果我。

现在我也明白Ruby的默认字符编码使用UTF-8,因此可以使用数千个可能的字符。因此,如果我问这样的事情:

'好'.ord

我得到该字符的位置是22909.但是,如果我在该值上调用chr

22909.chr

我得到“RangeError:22909超出char范围。”我只能让char处理最大为255的值,即扩展的ASCII。所以我的问题是:

  • 为什么Ruby似乎从扩展的ASCII字符集中获取chr的值,而从UTF-8中获取ord
  • 有没有办法告诉Ruby在使用这些方法时使用不同的编码?例如,告诉它使用ASCII-8BIT编码而不是它默认为什么?
  • 如果可以更改默认编码,是否有任何方法可以获得正在使用的集合中可用的字符总数?

2 个答案:

答案 0 :(得分:4)

根据Integer#chr,您可以使用以下命令强制编码为UTF_8。

Encoding.name_list
#=> ["ASCII-8BIT", "UTF-8", "US-ASCII", "UTF-16BE", "UTF-16LE", "UTF-32BE", "UTF-32LE", "UTF-16", "UTF-32", ...]

列出所有可用的编码名称

2000000.times.reduce(0) do |x, i|
  begin
    i.chr(Encoding::UTF_8)
    x += 1
  rescue
  end

  x
end
#=> 1112064

获得最大字符数的hacky方式

import { createSelector } from 'reselect'
import { denormalize } from 'denormalizr'
import { challenge as schema } from './challenge.schema'

const getState = (state) => state

export const getChallenge = createSelector(getState, ({ entities, challenge }) => {
  return denormalize(entities.challenges[challenge.item], entities, schema)
})

export const getChallenges = createSelector(getState, ({ entities, challenge }) => {
  return challenge.items.map((id) => denormalize(entities.challenges[id], entities, schema))
})

答案 1 :(得分:0)

经过一段时间的工作后,我意识到我可以通过运行二进制搜索来找到每个编码的最大字符数,以找到不会抛出RangeError的最高值。

def get_highest_value(set)
  max = 10000000000
  min = 0
  guess = 5000000000

  while true
    begin guess.chr(set)
      if (min > max)
        return max
      else
        min = guess + 1
        guess = (max + min) / 2
      end
    rescue
      if min > max
        return max
      else
        max = guess - 1
        guess = (max + min) / 2
      end
    end
  end
end

方法的输入值是要检查的编码的名称。