`
Hooopo
  • 浏览: 336661 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

UTF8编码和正则表达式

    博客分类:
  • Ruby
阅读更多
ruby的编码问题是每一个ruby初学者的最大困扰。下面把我的总结和大家分享一下,希望对大家有帮助。
注:系统windows xp 平台:ruby 1.8.6 (without rails)
1。编辑器
windows下大多数编辑器(比如irb,ruby自带的SciTE)不支持UTF-8编码,所以解决编码问题最先是换个支持UTF-8编码的编辑器,比如Netbeans,这样才能保证你的输入字符编码是UTF-8.
有了UTF-8编码的编辑器还不够,还要保证输出端不出现乱码,那就一定要用iconv这个库转换。因为ruby程序输出都是在windows 的cmd控制台的,而控制台的编码是GBK。
require'iconv'
class String
 def to_gbk
  Iconv.iconv("GBK//IGNORE","UTF-8//IGNORE",self).to_s
 end
 def to_utf8
  Iconv.iconv("UTF-8//IGNORE","GBK//IGNORE",self).to_s
 end
end
utf8_string="\344\273\254"
puts utf8_string #在irb中输出“浠”=>乱码
puts utf8_string.to_gbk #在irb中输出“们”=>正确输出
#在irb输入一汉字
gbk_string="\303\307"
puts gbk_string #输出"们"
p gbk_string.to_utf8 #输出"\344\273\254"

判断一个段文本是否是UTF-8编码:
class String
 def utf8?  
        unpack('U*') rescue return false  
        true  
 end
end
utf8_string.utf8? #true
gbk_string.utf8? #false


上面介绍了如何输入,显示,判断和转换utf8字符。但是只有这些还不够,下面绍如何处理。
ruby默认处理字符是按照ascii编码方式(这个和你输入的编码方式无关)
比如:
puts utf8_string.size #输出3
puts gbk_string.size #输出2

从这个例子我们可以看到,size方法的返回值实际上是这个字符串在某个固定的字符集下被编码为几个字节,从而返回它
jcode库还提供了一些有用的方法,比如jlength和each_char.
用jcode之前必须设置$KCODE="UTF-8"
$KCODE="u"
require'jcode'
puts utf8_string.size #还是3
puts utf8_string.jsize #1,正是我们想要的结果
puts gbk_string.jsize #也是1

这里还有一个方法,叫做mbchar?的,他检测一个字符串是否是多字节的.
puts utf8_string.mbchar? #0
puts gbk_string.mbchar? #nil 这个有点问题了.....
puts "aaaaa".mbchar? #nil

jcode库还重新定义了chop, delete, squeeze, succ, tr, 和tr_s.这些方法.这些方法都是为多字节的字符串所定义的
我们还可以使用each_char来打印出所有的多字节字符:
str=utf8_string << "hello"
str.each_char.map {|e| e.to_gbk} #=> ["们", "h", "e", "l", "l", "o"]
str.each_char.map {|e| [e.size,e.jsize]} #=> [[3, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1]]

unpack方法,有选项来帮助我们操作unicode字符串,如果他的参数为U*的话,则将会解码当前的字符串,使用utf-8编码。也就是说他会返回一个整数数组,而对应的还有一个pack方法,他则是编码的:
string=(utf8_string << "hooopo")*10
puts string.unpack("U*") #=> [20204, 104, 111, 111, 111, 112, 111, 20204, 104, 111, 111, 111, 112, 111, #20
#204, 104, 111, 111, 111, 112, 111, 20204, 104, 111, 111, 111, 112, 111, 20204, 1
#04, 111, 111, 111, 112, 111, 20204, 104, 111, 111, 111, 112, 111, 20204, 104, 11
#1, 111, 111, 112, 111, 20204, 104, 111, 111, 111, 112, 111, 20204, 104, 111, 111
#, 111, 112, 111, 20204, 104, 111, 111, 111, 112, 111]

用unpack做提取中文字符等操作是相当强大的:
string.unpack("U*").select{|e| (0x4E00..0x9FA5).include?e}.pack("U*").to_gbk
 #=> "们们们们们们们们们们"

当然提取中文可以用scan
string.scan(/./u).select{|e| e.size==3}.join.to_gbk
#=> "们们们们们们们们们们"

有个bug就是size==3的不一定是中文,也有可能是日文。。。但是这个对处理中文网页是没什么问题的。
提取字符串最强大的还是正则表达式,不过对中文这个问题,貌似ruby1.8.6的正则表达式不是很好处理
s=[0x4E00].pack("U")
e=[0x9FA5].pack("U")
reg=Regexp.new("[#{s}-#{e}]",false,"U")
puts string.scan(reg).join.to_gbk
#=> "们们们们们们们们们们"


这里说明一下,虽然ruby默认处理字符串的方式是按照ascii,但是如果设置$KCODE="u"会按照UTF-8方式处理,但是在正则表达式中只要设置正则字面量u(/reg/u)就会安装utf8方式处理,多以,如果知道要匹配字符范围的话,ruby 1.8.6的正则表达式也能很好的处理utf8
其他相关:
1.这里是pack和unpack的中文介绍http://www.souzz.net/html/345/23498.html
2.ruby每周一测-中英文混合字符串截取http://www.iteye.com/topic/201531
3. icu4r: IBM ICU库的Ruby扩展,添加了诸如UString, URegexp等类来处理Unicode。(文档链接)http://icu4r.rubyforge.org/
4.utf8proc: 一个很小型的库,便利字符串中的的字符然后一个个转过去,给String类和Interger类添加了了一些方法,比如String#utf8map和Integer#utf8 http://www.flexiguided.de/publications.utf8proc.en.html

分享到:
评论
9 楼 Hooopo 2009-04-20  
sevk 写道
如果在LINUX下面写代码,与出来一般是UTF-8的.有时候也需要转化成 GB18030 才能兼容 WINDOWS 系统.


额,,,还是linux好~
8 楼 Hooopo 2009-04-20  
tanggq 写道
正则表达式是支持utf-8,但支持GBK不好

ruby有没有多字节处理类?可任意转换的?

如php中有mb_string,可以多数编码长度,取子串,支持中英文

是的,貌似ruby 1.9的正则好很多。
标准库貌似只有jcode库吧~~
7 楼 sevk 2009-04-20  
如果在LINUX下面写代码,与出来一般是UTF-8的.有时候也需要转化成 GB18030 才能兼容 WINDOWS 系统.
6 楼 tanggq 2009-04-20  
正则表达式是支持utf-8,但支持GBK不好

ruby有没有多字节处理类?可任意转换的?

如php中有mb_string,可以多数编码长度,取子串,支持中英文
5 楼 Hooopo 2009-04-18  
如果你不是用的cmd或irb做输出端,可以把上面示例代码中的to_gbk去掉。
4 楼 Hooopo 2009-04-18  
以前一直用cmd做输出端,被输出的乱码困扰很久,原来SciTE可以设置输出端编码方式,我火星了!!
3 楼 Hooopo 2009-04-18  
更正一点:
SciTE是支持UTF-8的,在SciTE做如下设置

# Internationalisation
# Japanese input code page 932 and ShiftJIS character set 128
#code.page=932
#character.set=128
# Unicode
code.page=65001 #你输入的代码的编码的编码方式设置为UTF-8
#code.page=0
#character.set=204
# Required for Unicode to work on GTK+:
#LC_CTYPE=en_US.UTF-8
output.code.page=65001 #ScitE控制台输出编码设置为UTF-8,这样按F5后输出编码即为UTF-8

2 楼 Hooopo 2009-04-17  
<div class="quote_title">devworks 写道</div>
<div class="quote_div">
<p>SciTE 支持 UTF-8</p>
<pre name="code" class="java"># Internationalisation
# Unicode
code.page=65001
#character.set=134
# Required for Unicode to work on GTK+:
#LC_CTYPE=en_US.UTF-8
output.code.page=
</pre>
<p> </p>
</div>
<p><br>原来在Options=&gt;SciTEGlobal.properties里面设置啊!!谢谢~~</p>
1 楼 devworks 2009-04-17  
<p>SciTE 支持 UTF-8</p>
<pre name="code" class="java"># Internationalisation
# Unicode
code.page=65001
#character.set=134
# Required for Unicode to work on GTK+:
#LC_CTYPE=en_US.UTF-8
output.code.page=
</pre>
<p> </p>

相关推荐

    C语言正则表达式库

    它包含了对UTF-8编码的内置支持,并可以通过配置支持其他Unicode编码格式。 3. **回溯算法**:PCRE库使用了高效的回溯算法来执行正则表达式匹配。虽然这可能会导致性能问题,但通过优化的匹配引擎和使用预编译模式...

    易语言正则表达式匹配中文

    例如,可以使用两个字节的UTF-8编码来表示中文字符,其对应的正则表达式可能是`\xd0[\x80-\xff]|\xe0[\xa0-\xbf][\x80-\xbf]|\xed[\xa0-\xed][\x80-\xbf]`。这个表达式涵盖了大部分常用中文字符的UTF-8编码。 在...

    判断不同编码的正则表达式

    对于不同的字符编码(如GB2312、UTF-8等),其对应的正则表达式也会有所不同。本文将探讨如何通过PHP语言中的正则表达式来判断字符串是否为GB2312或UTF-8编码。 #### GB2312编码判断 GB2312是中国大陆使用的一种...

    VC++支持中文的正则表达式函数库

    - **编码支持**:由于库专门优化了对中文的支持,因此可能使用了宽字符或者UTF-8编码,确保你的项目设置与之兼容。 - **性能**:尽管库是为VC++定制的,但其性能可能与原生的正则表达式库(如Boost.Regex或std::...

    正则表达式提取网页编码

    本文将深入探讨如何利用正则表达式来提取网页中的编码信息。 ### 正则表达式提取网页编码 在网页中,编码信息通常位于`&lt;meta&gt;`标签内,通过`charset`属性指定。例如,在以下HTML代码片段中: ```html ;charset=...

    《正则表达式大全(上)》(高清晰)pdf版

    《正则表达式大全(上)》是一本深入讲解正则表达式的电子书籍,主要针对计算机领域的专业人士和学习者,提供了丰富的正则表达式实例及其应用场景。正则表达式是一种强大的文本处理工具,用于模式匹配、查找、替换等...

    正则表达式测试工具

    5. **编码支持**:处理不同编码的文本,如ASCII、UTF-8等。 6. **模式调试**:提供调试模式,查看匹配的每一个细节,如匹配的子串、捕获组等。 7. **学习资源**:部分工具内嵌正则表达式教程,方便初学者学习。 在...

    正则表达式乱码查看器

    "正则表达式乱码查看器"通过其内置的解码功能,可以有效地识别和显示这些乱码,帮助用户准确地查看原本被编码问题掩盖的信息。 "乱码查看器.exe"是程序的主执行文件,用户可以通过运行这个文件启动软件。它可能包含...

    mingw pcre8.12正则表达式库

    此外,PCRE还支持UTF-8编码,可以处理多语言字符,以及Unicode属性支持,这对于处理全球化应用中的文本非常有用。 在实际编程中,你可能需要了解PCRE的一些特殊标志和选项,如`PCRE_CASELESS`(不区分大小写)、`...

    正则表达式统计汉字

    这里的 `"utf-8"` 参数指定了字符串的编码方式,确保函数能够正确识别和计数。 ##### 5. 统计特定字符出现次数的方法 本例中,我们通过先用正则表达式移除所有非汉字字符,然后再统计剩余字符串的长度,以此来得到...

    正则表达式计数代码行数

    为了提高效率和准确性,还可以考虑使用预编译的正则表达式对象,并使用适当的方法处理编码问题。 在进行代码分析时,正则表达式的灵活性和强大功能使得它成为不可或缺的工具。通过熟练掌握正则表达式,开发者能够...

    易语言源码正则表达式匹配中文.7z

    在中文字符匹配方面,由于中文字符通常由多个字节组成,如UTF-8编码下每个汉字占用3个或4个字节,因此在编写正则表达式时需要特别考虑编码方式。在易语言中,我们可能需要使用支持多字节编码的正则库,如PCRE(Perl ...

    非常好用的正则表达式调试工具

    8. **编码支持**:处理不同编码格式的文本,如UTF-8、GBK等。 9. **自定义设置**:允许用户自定义匹配选项,例如是否区分大小写、是否全局匹配等。 10. **导出与分享**:能够导出测试用例或正则表达式,方便团队...

    C#字符串和正则表达式参考手册

    在第一章“系统处理文本的方式”中,作者介绍了计算机对文本的存储、编码方式,如ASCII、Unicode和UTF-8等,以及C#中的字符和字符串类型。这部分内容有助于理解不同编码格式间的转换和文本处理的基本原理。 第二章...

    C#正则提取中文

    然而,需要注意的是,正则表达式的编写需要对字符编码有深入的理解,尤其是当涉及到多字节字符集,如UTF-8、UTF-16等,因为不同的编码方式会影响正则表达式的匹配行为。此外,对于复杂的数据结构和模式,正则表达式...

    小巧强悍的工具Convert:正则表达式测试/代码转换/翻译/编解码/加解密

    4、Encoding&lt;-&gt;Decoding:编码和解码,包括Base64、UTF-8、Unicode、HTML(&)、URL(%)…… 5、Encryption&lt;-&gt;Decryption:加密和解密,包括高级标准算法(AES)、数据标准算法(DES)、三重数据标准算法(TripleDES)、...

    Python实现正则表达式匹配任意的邮箱方法

    同时,我们使用了coding声明来确保Python文件的编码为UTF-8,这对于处理包含中文字符的输入输出是很有必要的。 最后,通过对正则表达式的学习和实践,可以大幅度提高处理文本数据的能力,尤其在进行文本验证、数据...

    正则表达式测试软件_RegexBuddy

    5. **编码支持**:RegexBuddy支持多种字符编码,如ASCII、UTF-8等,这使得处理包含不同语言和特殊字符的文本变得轻松。 6. **跨平台兼容性**:虽然我们只提到RegexBuddy.exe,这通常意味着Windows版本,但该软件也...

    易语言正则表达式类匹配中文源码

    这通常涉及到对UTF-8编码的支持,因为中文字符在计算机中是以多字节的形式存储的,与英文字符的单字节编码有所不同。开发者可能需要编写或利用现有的易语言类来处理中文正则表达式,包括编译正则模式、执行匹配、...

    正则表达式 调试工具

    5. **编码支持**:支持多种字符编码,如ASCII、UTF-8等。 6. **错误提示**:当正则表达式有误时,提供清晰的错误信息,便于修正。 7. **学习资源**:一些工具还提供了正则表达式语法的学习资料,方便用户提升技能...

Global site tag (gtag.js) - Google Analytics