Showing posts with label unicode. Show all posts
Showing posts with label unicode. Show all posts

Friday, February 13, 2009

java unicode字符串转换

/**
* 转换unicode字符串为其对应的实际字符串, UnicodeToString("测试\\u4E2D\\u6587") 输出为: "测试中文"
*
* @param str
* @return
*/
public static String UnicodeToString(String str) {
Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
Matcher matcher = pattern.matcher(str);
char ch;
while (matcher.find()) {
ch = (char) Integer.parseInt(matcher.group(2), 16);
str = str.replace(matcher.group(1), ch + "");
}
return str;
}

Reference:
http://yuweijun.blogspot.com/2008/06/unicode.html
http://yuweijun.blogspot.com/2008/08/unicode-and-html-entities-in-javascript.html
http://yuweijun.blogspot.com/2008/12/rubyunicodeutf8.html

Friday, December 05, 2008

Hack ruby String#length

en = 'test'
cn = '一'
p en # >> "test"
p cn # >> "\344\270\200"
puts cn.inspect # >> "\344\270\200"
p "344".oct.to_s(16)
# >> "e4"
p "270".oct.to_s(16)
# >> "b8"
p "200".oct.to_s(16)
# >> "80"
p "344".oct
# >> 228
p "270".oct
# >> 184
p "200".oct
# >> 128
cn.scan(/./).each do |ch|
p ch, ch[0]
end

# hack ruby String#length
puts en.length # >> 4
puts cn.length # >> 3
puts en.scan(/./).length # >> 4
puts cn.scan(/./).length # >> 3
puts en.scan(/./u).length # >> 4
puts cn.scan(/./u).length # >> 1

Thursday, December 04, 2008

在Ruby中将unicode直接量转化成为utf8字符

require 'cgi'
def unicode_utf8(unicode_string)
unicode_string.gsub(/\\u\w{4}/) do |s|
str = s.sub(/\\u/, "").hex.to_s(2)
if str.length < 8
CGI.unescape(str.to_i(2).to_s(16).insert(0, "%"))
else
arr = str.reverse.scan(/\w{0,6}/).reverse.select{|a| a != ""}.map{|b| b.reverse}
# ["100", "111000", "000000"]
hex = lambda do |s|
(arr.first == s ? "1" * arr.length + "0" * (8 - arr.length - s.length) + s : "10" + s).to_i(2).to_s(16).insert(0, "%")
end
CGI.unescape(arr.map(&hex).join)
end
end
end

puts unicode_utf8('test\u4E2Dtest\u6587test\u6D4Btest\u8BD5test')

Sunday, October 12, 2008

Unicode spaces and RLO/LRO

<p>看下面2行的区别并复制下面第一行到任何文本编辑器中查看效果</p>
‮tset (e202u\:值edocinu)OLR符字制控
‭控制字符LRO(unicode值:\u202d) test
<p>其他Unicode空白字符</p>
<p>&#8234;&#8234;test</p>
<p>&#8235;&#8235;test</p>
<p>&#8236;&#8236;test</p>
<p>&#8237;&#8237;test</p>
<p>&#8238;&#8238;test</p>

另:这个如果用vim看的话,能看到这些unicode space characters,如\u202e这个在vim里会是<202e>这样的一个字符,可以被复制粘贴。
Reference:
http://www.cs.tut.fi/~jkorpela/chars/spaces.html

Saturday, October 11, 2008

utf-8和Unicode之间相互转换

UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

下表总结了编码规则,字母x表示可用编码的位。

Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

以汉字"严"为例,演示如何实现UTF-8编码。
已知"严"的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此"严"的UTF-8编码需要三个字节,即格式是"1110xxxx 10xxxxxx 10xxxxxx"。然后,从"严"的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,"严"的UTF-8编码是 "11100100 10111000 10100101",转换成十六进制就是E4B8A5。
在firebug中测试中文"胡"字:
>>> encodeURI('胡')
"%E8%83%A1"
>>> '胡'.charCodeAt().toString(16)
"80e1"
>>> '胡'.charCodeAt().toString(2)
"1000000011100001"
>>> parseInt('111010001000001110100001', 2)
15238049
>>> parseInt('111010001000001110100001', 2).toString(16)
"e883a1"

其中将1000000011100001对应位置补上110或者10,生成Unicode二进制值111010001000001110100001,反过来从Unicode转到UTF-8只要移除对应位置上的110和10即可得到UTF-8的二进制值。
Reference:
http://yuweijun.blogspot.com/2008/06/unicode.html
http://yuweijun.blogspot.com/2008/08/unicode-and-html-entities-in-javascript.html
http://dreamstone.javaeye.com/blog/77939

Sunday, August 31, 2008

unicode and html entities in javascript


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<script type="text/javascript" charset="utf-8">
var three = "叁";
// 单字符计算,多字符也可用此进行计算
var code = three.charCodeAt(0).toString(16); // 10进制转16进制
document.write(code);
document.write("<br/>");
document.write("&#x" + code + ";");
var decimal = parseInt(code, 16); // 16进制转10进制
document.write("<br/>");
document.write(decimal);
document.write("<br/>");
var san = String.fromCharCode(decimal);
document.write(san);
document.write("<br/>");
document.write("<br/>");

// javascript 支持unicode直接量
var unicode = "\u53c1"; // different from string "\\u" + "53c1"
document.write("<br/>");
document.write(unicode);
document.write("<br/>");
document.write("<br/>");

// 多字符转换,利用escape/unescape()方法进行转换,不推荐
var PRC = "中华人民共和国";
var entityChar = PRC.replace(/[^\u0000-\u00FF]/g, function($0){
return escape($0).replace(/(?:%u)(\w{4})/gi, "&#x$1;")
});
document.write("<br/>");
document.write(entityChar); // "中华人民共和国"
document.write("<br/>");
var origin = unescape(entityChar.replace(/&#x/g, '%u').replace(/;/g, ''));
document.write(origin);
</script>
</body>
</html>

unicode编码规则:
unicode码对每一个字符用4位16进制数表示。具体规则是:将一个字符(char)的高8位与低8位分别取出,转化为16进制数,
如果转化的16进制数的长度不足2位,则在其后补0,然后将高、低8位转成的16进制字符串拼接起来并在前面补上"\u"即可。

Saturday, June 28, 2008

java bin目录下的native2ascii使用

直接在命令行中输入native2ascii后可以进入控制台,输入字符串之后native2ascii会将字符串转为unicode编码。
$> native2ascii
test中文
test\u2030\u220f\u2260\u00ca\u00f1\u00e1

Tuesday, June 10, 2008

字符串与unicode编码的相互转换

unicode编码简而言之就是将每一个字符用16位2进制数标识。但是通常都用4位的16进制数标识。
例如:
1)中文字符串"你好"的unicode码为:\u4f60\u597d;
2)英文字符串"ab"的unicode码为:\u0061\u0062;
其中\u是标识unicode码用的,后面的4位16进制数则是对应字符的unicode码。

1、unicode编码规则
unicode码对每一个字符用4位16进制数表示。具体规则是:将一个字符(char)的高8位与低8位分别取出,转化为16进制数,
如果转化的16进制数的长度不足2位,则在其后补0,然后将高、低8位转成的16进制字符串拼接起来并在前面补上"\u" 即可。

2、用java代码说明unicode的编码规则 [java的unicode解码编码的代码详见javaeye的帖子]

public class Unicode {

public static void main(String[] args) {
char c = '一'; // 一(4e00)是unicode中文字符集首字,龥(9fa5)是unicode中文字符集尾字
int i, j;
i = c & 0xFF;
j = c >>> 8;
System.out.println("Original character is: " + c);
System.out.println("low 8 bit is: " + i);
System.out.println("high 8 bit is: " + j);
}

}
$> javac Unicode.java
$> java Unicode
Original character is: 一
low 8 bit is: 0
high 8 bit is: 78
78转为16进制为4e,将高、低8位转成的16进制字符串拼接起来即为\u4e00,这就是中文字"一"的unicode编码。
在ajax请求返回的responseText或者json数据可以先在服务器端编码为unicode格式传给客户端浏览器,这样客户端的页面无论是什么编码,js都可以很好的处理返回的内容。
4e00的十进制值为4 * 16 * 16 * 16 + 14 * 16 * 16 + 0 * 16 + 0 = 19968
网页中则可以用&#19968;来表示中文字"一",这样不论网页以何种编码,页面始终都可以正常显示,而不会出现乱码。这种方法以前在做wap项目常常将页面上所有中文字都用unicode编码后发布,就是为了避免乱码问题。

3、javascript代码,验证字符串中是否包括中文字
/[\u4e00-\u9fa5]/.test(str)

4、ruby中验证字符串中是否包括中文字
/[一-龥]/ =~ str

Reference:
http://haoi77.javaeye.com/blog/198840

Number toString 方法使用

Number.toString(radix)
Converts a number to a string, using a specified radix (base), and returns the string. radix must be between 2 and 36. If omitted, base 10 is used.
比如中文“一”字的unicode编码为\u4e00,要想得到对应的unicode十进制编码,在js中不必用4 * 16 * 16 * 16 + 14 * 16 + 0 + 0 = 19968来获得,可以直接用Number.toString()方法得到:
(0x4e00).toString(10) = "19968"
这样得到的值可以再用js加上前后缀成为"&#" + "19968" + ";" = "一"后可以直接从网页中输出。
反过来,如果知道十进制的一个数字,也可以很容易转换成16进制的值:
(19968).toString(16) = "4e00"