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 "".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=
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 "".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

 

ruby 程序中的文字编码的更多相关文章

  1. Javascript中对文字编码的三个函数

    JavaScript中对文字编码主要有3个函数 escape,encodeURI, encodeURIComponent 相应3个解码函数 unescape, decodeURI, decodeURI ...

  2. py3中的文字编码

    Python3 中字符的类型只有两种: str: 编码过的 unicode 文本字符 bytes: 编码前的字节序列

  3. [译]在 Andriod/IOS 程序中使用自己的字体

    原文链接:http://firemonkeyblog.blogspot.com/2014/12/using-custom-fonts-in-android-delphi.html 你应该能够在 And ...

  4. 1 byte 8 bit 1 sh 1 bit 2. 字符与编码在程序中的实现

    https://en.wikipedia.org/wiki/Shannon_(unit) 1字节(英语:Byte)=8比特(英语:bit) The shannon (symbol Sh), also ...

  5. 编码占用的字节数 1 byte 8 bit 1 sh 1 bit 中文字符编码 2. 字符与编码在程序中的实现 变长编码 Unicode UTF-8 转换 在网络上传输 保存到磁盘上 bytes

    小结: 1.UNICODE 字符集编码的标准有很多种,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等: 2 服务器->网页 utf-8 ...

  6. 如何:通过对字符串应用 HTML 编码在 Web 应用程序中防止脚本侵入

    大多数脚本利用发生在用户可以将可执行代码(或脚本)插入您的应用程序时. 默认情况下,ASP.NET 提供请求验证.只要窗体发送包含任何 HTML,该验证都会引发错误. 您可以使用下列方法防止脚本利用: ...

  7. 如何:通过将HTML编码应用于字符串来防止Web应用程序中的脚本漏洞

    当用户可以将可执行代码(或脚本)添加到您的应用程序中时,会发生大多数脚本攻击.默认情况下,ASP.NET提供请求验证,如果表单发布包含任何HTML,则会引发错误. 您可以通过以下方式帮助防止脚本漏洞利 ...

  8. JS事件 内容选中事件(onselect)选中事件,当文本框或者文本域中的文字被选中时,触发onselect事件,同时调用的程序就会被执行。

    内容选中事件(onselect) 选中事件,当文本框或者文本域中的文字被选中时,触发onselect事件,同时调用的程序就会被执行. 如下代码,当选中用户文本框内的文字时,触发onselect 事件, ...

  9. CocoaPods:管理Objective-c 程序中各种第三方开源库关联

    在我们的iOS程序中,经常会用到多个第三方的开源库,通常做法是去下载最新版本的开源库,然后拖拽到工程中. 但是,第三方开源库的数量一旦比较多,版本的管理就非常的麻烦.有没有什么办法可以简化对第三方库的 ...

随机推荐

  1. apk重新签名

    re-sign.jar中后自动去除签名这个方法,经试验不可用! 1.去除准备重新签名SinaVoice.apk软件本身的签名 将apk文件后缀改为.zip,然后从winrar中删除META-INF文件 ...

  2. Android开发-API指南-<compatible-screens>

    <compatible-screens> 英文原文:http://developer.android.com/guide/topics/manifest/compatible-screen ...

  3. nginx+lua+redis初体验

    1.下载nginx.lua.redis nginx下载地址 wget  http://nginx.org/download/nginx-1.8.0.tar.gz lua下载地址 wget http:/ ...

  4. 操作系统是怎么工作的——函数的堆栈框架/嵌入式代码

    1.函数堆栈框架 1.1框架模型 call指令: 1)将eip中的下一条指令的地址A保存在栈顶: 2)设置eip指向被调用程序的代码处. ret指令:将地址A恢复到eip中 这样就将函数的调用变为顺序 ...

  5. MSP430F149学习之路——按键与LED

    代码 /*********************************** 程序功能:用按键控制LED状态 缺点:按键按下后无法改变LED灯的状态,可以利用板上的复位键^~^ ********** ...

  6. JS 点击按钮后弹出遮罩层,有关闭按钮

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  7. dell 网络产品线

    https://en.wikipedia.org/wiki/Dell_Networking_Operating_System http://topics-cdn.dell.com/pdf/ DNOS ...

  8. 【Linux】基于Bind_DLZ和MySQL数据的DNS搭建

    参考:http://www.linuxfromscratch.org/blfs/view/cvs/server/bind.html 参考:http://bind-dlz.sourceforge.net ...

  9. Acronis 备份使用

    1:至Acronis 中国官网,可了解到:Acronis True Image 是PC产品,Acronis Backup是企业产品 2:Acronis Backup 11.5.0.39029 :htt ...

  10. C# 和SQL Server 类型转换

    /// <summary> /// 数据库中与C#中的数据类型对照 /// </summary> /// <param name="type"> ...