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. 解决:对 PInvoke 函数的调用导致堆栈不对称问题 <转载>

    问题描述: 在使用托管代码调用非托管代码时,发生“对 PInvoke 函数“UseTwiHikVisionDllTest!UseTwiHikVisionDllTest.TwiHikVision::Ge ...

  2. python-appium手机自动化测试(仅需安装包)前期准备(pydev-eclipse编辑器)

    1.jdk安装与环境变量配置教程http://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.html 我本机安装的是1.6.043 2.sdk下 ...

  3. 查看mysql 的物理存储路径

    mysql> show global variables like "%datadir%";

  4. Apache FtpServer扩展【动手实现自己的业务】

    Apache FtpServer是当下最热门的走ftp协议的用于用户上传下载的服务器. 官网http://mina.apache.org/ftpserver-project/   一般来说,用的话,去 ...

  5. Quick Sort(快排)

    这是挖坑填补法的演示 快排之挖坑填补法: void Quick(int top/*起始位置*/,int end/*末尾位置*/,int arr[])//挖坑填补法 { int i=top,j=end, ...

  6. 同步灵无线锂电鼠G11-580HX独特“五灵键”

    http://tieba.baidu.com/p/2130455709 现在鼠标功能越来越强大,游戏鼠标的宏设置,办公鼠标的复制粘贴等.各位有没有给鼠标设置一些好玩.方便.搞怪.有意思的的功能的呢?笔 ...

  7. 循环链表Josephus问题(c,cpp)

    问题描述: 设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m个的人出列,然后从出列的下一个人重新开始报数,数到第m个的人又出列,.......,如此反复直到所有的人出列为止. Joseph ...

  8. 华为OJ平台——超长正整数相加

    题目描述: 请设计一个算法完成两个超长正整数的加法. 输入 输入两个字符串数字 输出 输出相加后的结果,string型 样例输入 99999999999999999999999999999999999 ...

  9. 二模10day2解题报告

    T1.最多因子数(divisors) 给出范围l,r求其中约数和最大的最小整数. 非常深井冰的题目:如果特判加暴力的话分数低的可怜 AC做法要用到分解质因数和线性筛(这俩好写),然而,一个一个枚举还是 ...

  10. 使用VS2012生成DLL文件 (1)

    一:生成DLL 1:创建DLL工程 文件->新建->项目->visual c++->win32->win32控制台应用程序(win32项目也可以) 填写项目名称MyDLL ...