• ruby 程序中的文字编码


    1,问题

    在写一个统计代码行数的脚本时遇到一个问题:

    代码:

    file_name = "code.rb"
    c = 0
    File.foreach(file_name) do |x| next unless x !~ /^s*(#|s*$)/ c = c + 1 end

    运行的时候报错

    ArgumentError: invalid byte sequence in GBK
            =~ at org/jruby/RubyRegexp.java:1486
            =~ at org/jruby/RubyString.java:1652
            !~ at org/jruby/RubyKernel.java:2158
      __file__ at ddd.rb:20
       foreach at org/jruby/RubyIO.java:3352
        (root) at ddd.rb:17

    提示说GBK编码中有不识别的内容。大概情况是这样(有待考证),由于使用的是中文的操作系统(win7),ruby根据系统的语言,采用对应编码方式(GBK),从文件中取得的字符串默认为GBK的格式。

    file_name = "code.rb"

    c = 0
    File.foreach(file_name)  do
        |x|
        p x.encoding
        next unless x !~ /^s*(#|s*$)/u
        c = c + 1
    end
    p "1234567890"
    .encoding
    
    

    得到的结果是:

    #<Encoding:GBK>
    #<Encoding:GBK>
    #<Encoding:GBK>
    #<Encoding:US-ASCII>

    从文件中取得内容是GBK的,一个普通的字符串是ASCII。

    如果给rb脚本加上# -*- coding:utf-8 -*-,即:

    # -*- coding:utf-8 -*-
    
    file_name = "code.rb"

    c = 0
    File.foreach(file_name)  do
        |x| 
    p x.encoding

    next unless x !
    ~ /^s*(#|s*$)/u
    c = c + 1
    end
    p
    "1234567890".encoding

    这时会将普通字符串的格式都默认为UTF-8,而从文件中读取的内容呢?请看结果:

    #<Encoding:GBK>
    #<Encoding:GBK>
    #<Encoding:GBK>
    #<Encoding:UTF-8>

    结果显示,从文件中读取的内容和设置的rb程序编码方式是无关的。

    对于要读取的文件是UTF-8格式,而取得的字符串却是GBK,做正则表达式判断的时候就会报错了。对于这种情况,可以设置取文件时采用UTF-8,好像只有open方法有此选项:

    # -*- coding:utf-8 -*-
    file_name = "code.rb"

    c= 0
    open(file_name, "r:utf-8") do |f|
        f.each do |line|
            next unless line !~ /^s*(#|s*$)/
            c = c + 1
            p line.encoding
        end
    end
    
    p "1234567890".encoding

    结果是:

    #<Encoding:UTF-8>
    #<Encoding:UTF-8>
    #<Encoding:UTF-8>
    #<Encoding:UTF-8>

     2,结论:

    # -*- coding:utf-8 -*-   
    影响的是rb代码中普通字符串的编码方式。
    open(file_name, "r:utf-8")可以控制读取文件中编码方式。

    查阅资料的过程中涉及到了
    $KCODE = 'u'   # 或者为$KCODE = 'utf-8' 

    《ruby程序设计268技》中说,默认的文字编码可以通过$KCODE环境变量设置,可实际操作过程中,并没有效果。

    《松本行弘的程序世界》中说,给全局变量$KCODE设置适当的值,可以给不带选项的正则表达式制定编码方式。

    $KCODE = 'e'
    #全部的文本按照EUC-JP为基础
    $KCODE = 'u'
    #全部的文本按照UTF-8为基础
    re = /foo 認証情報の入力/u
    #UTF-8对应的正则表达式(u选项制定)
    chars = 'abc 認証情報の入力'.split(//u)
    #以问子伟单位分割string

    附字符串的UTF-8 和GBK的转换方法:

    require 'iconv'
    def utf82gb(str)
      Iconv.iconv("GBK",'UTF-8',str.to_s)
    end

     -----------------以下更新于2014年3月8日-----------

    根据双飞燕《Ruby编程语言》,2.4.2源编码和默认外部编码

    源编码:Ruby解释器解读脚本中的字符,通常采用编码注释来设定一个文件的源编码,例如:# coding: utf-8

    默认外部编码:Ruby从文件或者流中读取内容时采用的默认编码,对于ruby来说是全局性的,基于电脑的区域设置来进行设置的,和电脑的操作系统语言相关。

    脚本中打印 Encoding.default_external,输出结果是#<Encoding:GBK>,因为返回的是Encoding对象。

    可以通过如下四种方式设置默认外部编码:

    ruby -E utf-8

    ruby -Eutf-8

    ruby --encoding utf-8

    ruby --encoding=utf-8

     
  • 相关阅读:
    gitlab 搭建(基于现有nginx)
    CENTOS 7平滑升级PHP到最新版7.3
    zabbix 5.0安装
    禅道 基于原lnmp 搭建
    mysql5.5升级至5.7 或升级至8.0
    gitlab搭建
    Autoboxing an autounboxing in genral
    java concurrency
    Why use interface type to declare a collectio
    Java coding style
  • 原文地址:https://www.cnblogs.com/fanxiaopeng/p/3480180.html
Copyright © 2020-2023  润新知