Erlang的Unicode支持

在R13A中, Erlang加入了对Unicode的支持。本文涉及到的数据类型包括:list, binary, 涉及到的模块包括stdlib/unicode, stdlib/io, kernel/file。 
Binary

Binary的type属性增加了utf相关的type:utf8, utf16, utf32,其分别对应UTF8, UTF16,UTF32编码。

Binary Constructing

在Binary构建时, 如果指定了utf相关类型,那么对应的integer的Value必须位于:0..16#D7FF, 16#E000..16#FFFD, 或者 16#10000..16#10FFFF这三个区间中。否则将会提示‘bad argument‘,参数错误。根据指定的的utf类型不同,同一个数据产生的binary不同。

对于utf8,每个integer生成1到4个字符;对于utf16,每个integer生成2或4个字符;对于utf32,每个integer生成4个字符。

比如, 使用unicode为1024的字符A,  构建一个binary:

Erlang代码

  1. 1> <<1024/utf8>>.
  2. <<208,128>>
  3. 2> <<1024/utf16>>.
  4. <<4,0>>
  5. 3> <<1024/utf32>>.
  6. <<0,0,4,0>>

Binary Match

当进行Binary Match时,如果指定utf相关类型,变量成功匹配后,将拥有一个位于:0..16#D7FF, 16#E000..16#FFFD, 或者 16#10000..16#10FFFF这三个区间中的integer。

其更具utf类型的不同,消耗(match)不同数目的bytes。

utf8匹配1-4个bytes(参考RFC-2279) 
utf16匹配2 或 4 个bytes (参考 RFC-2781) 
utf32匹配4个 bytes

比如:继续我们上面的例子

Erlang代码

  1. 4> Bin = <<1024/utf8>>.
  2. <<208,128>>
  3. 5> <<U/utf8>> = Bin.
  4. <<208,128>>
  5. 6> U.
  6. 1024

这个例子中,U匹配了2个bytes。

对于utf相关类型,不能指定unit spec

List

在list中,每个unicode字符采用integer来表示,因此与latin1的list相比,unicode list中,element的数值可以大于255。 
下面就是一个有效的unicode list: [1024, 1025]

我们可以通过unicode 模块实现 list到binary的转换。

unicode module

首先请参看下面的type定义:

unicode_binary() = binary() with characters encoded in UTF-8 coding standard 
unicode_char() = integer() representing valid unicode codepoint 
chardata() = charlist() | unicode_binary() 
charlist() = [unicode_char() | unicode_binary() | charlist()] 
a unicode_binary is allowed as the tail of the list

external_unicode_binary() = binary() with characters coded in a user specified Unicode encoding other than UTF-8 (UTF-16 or UTF-32) 
external_chardata() = external_charlist() | external_unicode_binary() 
external_charlist() = [unicode_char() | external_unicode_binary() | external_charlist()] 
an external_unicode_binary is allowed as the tail of the list

latin1_binary() = binary() with characters coded in iso-latin-1 
latin1_char() = integer() representing valid latin1 character (0-255) 
latin1_chardata() = latin1_charlist() | latin1_binary() 
latin1_charlist() = [latin1_char() | latin1_binary() | latin1_charlist()] 
a latin1_binary is allowed as the tail of the list

我们可以调用unicode:characters_to_list/1 将chardata或latin1_chardata或external_chardata()转化成一个unicode list。

如果参数为latin1_chardata,那么Data参数就是一个iodata. 返回的结果list中,每个element为一个integer。默认情况 unicode:characters_to_list/1调用unicode:characters_to_list(Data, unicode)

如果我们的CharData为其他类型,我们可以指明InEncoding type。如果此函数执行成功,返回{ok, List}, 如果失败返回{error, list(), RestData}, 其中list为转化成功的部分,RestData为发生错误的位置。

我们也可以调用unicode:characters_to_binary/1,将chardata或latin1_chardata或 external_chardata()转化成一个binary。这个函数和unicode:characters_to_list类似,只是结果保存为 binary。

如果Data为latin1_chardata, 那么unicode:characters_to_binary/1和 erlang:iolist_to_binary/1功能相同

unicode模块中,还有两个于bom相关的函数,可以根据bom指返回对应的encoding类型,也可以根据encoding类型生成对应的bom值。其在保存文件时,经常使用.

Examples

1, 打开utf8保存的文件 
  文件内容如下test.file: 

{desc, "这是一个测试文件"}, 
{author, "litaocheng"} 
].

其格式为erlang term,保存时选择utf8编码。 
代码如下:

Erlang代码

  1. %% read content from the file
  2. test1() ->
  3. {ok, [Terms]} = file:consult("test.txt"),
  4. Desc = proplists:get_value(desc, Terms),
  5. _Author = proplists:get_value(author, Terms),
  6. % out put the Desc and Author
  7. DescUniBin = iolist_to_binary(Desc),
  8. DescUniList = unicode:characters_to_list(DescUniBin),
  9. io:format("desc bin : ~ts~ndesc bin : ~p~n",[DescUniBin, DescUniBin]),
  10. io:format("desc list: ~ts~ndesc list: ~p~n", [DescUniList, DescUniList]).

结果: 
desc bin : 这是一个测试文件 
desc bin : <<232,191,153,230,152,175,228,184,128,228,184,170,230,181,139,232, 
             175,149,230,150,135,228,187,182>> 
desc list: 这是一个测试文件 
desc list: [36825,26159,19968,20010,27979,35797,25991,20214]

首先将内容从list转换为binary, DescUniBin 便是对应的unicode binary。随后通过unicode:characters_to_list/1转化为unicode list最后输出。 
我们可以看到 unicode list中所有的element为integer, unicode binary中unicode string采用uft8编码。

2, 将数据保存成uft8格式

Erlang代码

  1. %% save the binary in utf8 format
  2. test2() ->
  3. [DescList] = io_lib:format("~ts", ["这是一个测试文件"]),
  4. DescBin = erlang:iolist_to_binary(DescList),
  5. DescList2 = unicode:characters_to_list(DescBin),
  6. List = lists:concat(["[{desc,\"", DescList2, "\"}, {author, \"litaocheng\"}]."]),
  7. Bin = unicode:characters_to_binary(List),
  8. io:format("bin is:~ts~n", [Bin]),
  9. file:write_file("test_out.txt", Bin).

Update: 
2008.5.4: 
[DescList] = io_lib:format("~ts", ["这是一个测试文件"]) 
在erlang shell中DescList为:[36825,26159,19968,20010,27979,35797,25991,20214] 
在module文件中,DescList为: 
[232,191,153,230,152,175,228,184,128,228,184,170,230,181,139,232,175, 
          149,230,150,135,228,187,182]

时间: 2024-11-13 10:37:58

Erlang的Unicode支持的相关文章

[Erlang 00124] Erlang Unicode 两三事 - 补遗

最近看了Erlang User Conference 2013上patrik分享的BRING UNICODE TO ERLANG!视频,这个分享很好的梳理了Erlang Unicode相关的问题,基本上把 Using Unicode in Erlang 讲解了一遍.再次学习了一下,整理成文字,补充一些 [Erlang 0062] Erlang Unicode 两三事 遗漏掉的内容. 视频在这里: http://www.youtube.com/watch?v=M6hPLCA0F-Y PDF在这里:

【推介】TMS的控件之“TMS Unicode Component Pack”和“TMS Advanced Toolbars &amp; Menus”

TMS Unicode Component Pack是一款支持多语言的界面控件包,提供超过60种控件来为你的Delphi和C++Builder应用程序添加Unicode支持. 介绍: TMS Unicode Component Pack控制组件能让你在不终止Delphi.C++Builder或Windows 95/98/ME的情况下利用Windows NT/2000/XP/2003/Vista的Unicode功能开发应用程序.  注意:这些控制组件不会将Unicode功能添加到Windows 9

为什么我要选择erlang+go进行服务器架构

服务器非业余研究http://blog.csdn.net/erlib 作者Sunface 估计很多同学看到这里都会觉得迷惑,go的大名已经如雷贯耳了,但是erlang?这个东东是神马?难道是编程语言?怎么从来没听说过. 这里请允许我先介绍一下使用Erlang开发的比较有名的应用: 一:whatsapp 只凭32个技术人员,如何应付4.5亿的用户?对于刚刚被Facebook用190亿美元收购的WhatsApp来说,答案是Erlang--一种诞生于上世纪80年代的编程语言,终于在此时走到了聚光灯下.

Unicode代码点与编码方式

一.Unicode字符集 UTF编码,全称是Unicode Transformer Format,这种编码是UCS(Universal Mutiple-Octet Doded Character Set,国际标准ISO10646规定的通用字符集)的实际形式,它的分类是按照其基本长度所占用的位数而定,分为UTF-8/16/32三种形式.UTF可以说是其他字符集的集合,它使得其它字符集是交叉兼容的,可以说,凡是将文字符号转为UCS后再转回原来的编码,也不会丢失信息.UCS包含了现在所有的已知语言的字

[Python爬虫] 中文编码问题:raw_input输入、文件读取、变量比较等str、unicode、utf-8转换问题

最近研究搜索引擎.知识图谱和Python爬虫比较多,中文乱码问题再次浮现于眼前.虽然市面上讲述中文编码问题的文章数不胜数,同时以前我也讲述过PHP处理数据库服务器中文乱码问题,但是此处还是准备简单做下笔记.方便以后查阅和大家学习. 中文编码问题的处理核心都是--保证所有的编码方式一致即可,包括编译器.数据库.浏览器编码方式等,而Python通常的处理流程是将unicode作为中间转换码进行过渡.先将待处理字符串用unicode函数以正确的编码转换为Unicode码,在程序中统一用Unicode字

【Windows编程】系列第四篇:使用Unicode编程

上一篇我们学习了Windows编程的文本及字体输出,在以上几篇的实例中也出现了一些带有“TEXT”的Windows宏定义,有朋友留言想了解一些ANSI和Unicode编程方面的内容,本章就来了解和学习一些Windows下关于ANSI和Unicode方面的编程基础. 计算机最早在美国诞生,所以最开始都是以英语为作为交互语言,由于只有26个字母,用一个字节(范围-128 ~ 127)表示,这个范围足够表示26个因为字符和一些常用的控制字符,这个就是ASCII编码.因此最早的各种程序设计语言以及使用的

Erlang process structure -- refc binary

Erlang 的process 是虚拟机层面的进程,每个Erlang process 都包括一个 pcb(process control block), 一个stack 以及私有heap . 这部分的姿势, 在各种论文中都有提到. 网上也有各种各样的解读,包括但不仅限于: 1, http://fengchj.com/?p=2255 2, http://blog.csdn.net/mycwq/article/details/26613275 那么, 从现有的资料,可以看出,正因为在Erlang 虚

Python-正确使用Unicode

正确处理文本,特别是正确处理Unicode.是个老生常谈的问题,有时甚至会难倒经验丰富的开发者.并不是因为这个问题很难,而是因为对软件中的文本,开发者没有正确理解一些关键概念及其表示方法.在StackOverflow上搜索关于UnicodeDecodeError相 关的问题,可以看到很多人都有这样的误解.这些错误的概念可以追溯到Unicode出现之前.那时许多现今的开发者还没入职,也包括我自己.如果这些错误 的概念没有散布开来,其实不是个问题.现在很多人都有这些错误概念,部分原因是因为有些非常流

Unicode简介

Unicode简介 壹佰软件开发小组  整理编译   在第一章中,我已经预告,C语言中在Microsoft Windows程序设计中扮演着重要角色的任何部分都会讲述到,您也许在传统文字模式程序设计中还尚未遇到过这些问题.宽字符集和Unicode差不多就是这样的问题. 简单地说,Unicode扩展自ASCII字符集.在严格的ASCII中,每个字符用7位表示,或者计算机上普遍使用的每字符有8位宽:而Unicode使用全16位字符集.这使得Unicode能够表示世界上所有的书写语言中可能用于计算机通讯