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. Codeforces Round #218 (Div. 2) B. Fox Dividing Cheese

    B. Fox Dividing Cheese time limit per test 1 second memory limit per test 256 megabytes input standa ...

  2. bootstrap风格的multiselect插件——类似邮箱收件人样式

    在开发颗粒云邮箱的过程中,遇到了一个前端的问题,就是邮箱收件人的那个multiselect的input输入框.不仅能够多选,还要能够支持ajax搜索,把联系人搜索出来.就是类似下面的这个东西: 网上找 ...

  3. 消费者端的Spring JMS 连接ActiveMQ接收生产者Oozie Server发送的Oozie作业执行结果

    一,介绍 Oozie是一个Hadoop工作流服务器,接收Client提交的作业(MapReduce作业)请求,并把该作业提交给MapReduce执行.同时,Oozie还可以实现消息通知功能,只要配置好 ...

  4. 学习记录 java 值类型和引用类型的知识

    1. Java中值类型和引用类型的不同? [定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值, 那么调用这个方法是传入的变量的值也将改变 ...

  5. (转)TextView属性大全

    TextView属性大全 今天研究了TextView一天了,发现网上有一篇讲TextView属性的,非常全,收藏一下先. 发现TextView有一个比较大的问题,就是文字排版的问题,遇到数字,字母,符 ...

  6. TCP/IP详解学习笔记(2)-- 数据链路层

    1.概述      数据链路层属于计算机网络的底层,使用的信道主要有点对点信道和广播信道两种类型.      在TCP/IP协议族中,数据链路层主要有三个目的:           1)为IP模块发送 ...

  7. 【drp 9】Servlet生命周期

    一.基本概念 Servlet(Server Applet):全称Java Servlet,是用Java编写的服务器端程序.其主要功能在于交互式地浏览和修改数据,生成动态Web内容.狭义的Servlet ...

  8. [Nginx 1] Nginx简介

    导读:现在项目中用到这个Nginx了,本来是想着把代码调通了就得了.想想还是花点时间总结总结,就利用门卫思维吧.今天主要是一个整体的介绍,然后在学习的过程中,接着总结Nginx的其他使用事宜. 一.什 ...

  9. gerrit 调试smtp email

  10. jquery 设置元素内容html(),text(),val()

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...