Chinaunix首页 | 论坛 | 博客
  • 博客访问: 485010
  • 博文数量: 142
  • 博客积分: 4126
  • 博客等级: 上校
  • 技术积分: 1545
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-22 10:03
文章分类

全部博文(142)

文章存档

2011年(8)

2010年(7)

2009年(64)

2008年(63)

我的朋友

分类:

2008-12-15 17:25:36

1.1.1 提出问题

你有2个字符串,打印出来的时候看起来是一样的,但是用字符串比较操作的话它们又是不一样的,甚至有时它们的长度都不是一样的,你应该怎样才让Perl把它们当成一样的字符串呢?

1.1.2 解决方案

当你有一些在其他方面一样的字符串时,如果它们之中有一些含有Unicode combining character,那么你不要直接比较它们,先用Unicode::Normalize这个模块的NFD函数标准化之后再进行比较。
 
 

use Unicode::Normalize;
$s1 = "fa\x{E7}ade";
$s2 = "fac\x{0327}ade";
if (NFD($s1) eq NFD($s2)) { print "Yup!\n" }

1.1.3 讨论


一个字符有时可以有多个方法来表示。有时这是因为一些以前遗留下来的编码方法,像Latin1 里面那些包含变音符号的字符。这些字符可以直接用一个字符编码(比如U+00E7或者 LATIN SMALL LETTER C WITH CEDILLA)来表示,或者,通过基本字符尾跟一个combining character的方法来表示(比如U+0063或者LATIN SMALL LETTER C 尾跟一个U+0327或者COMBINING CEDILLA )。

有时候你可能要给一个基本字符添加2个以上的标记,这些标记在你的数据里面出现的先后顺序并不是固定的。假设你要给字符c 添加变音标记,以及在顶部添加caron标记来形成这样的字符: 。那么用下面的任意一种方法都可以实现:

 

$string = v231.780;
# LATIN SMALL LETTER C WITH CEDILLA

# COMBINING CARON


$string = v99.807.780;
# LATIN SMALL LETTER C

# COMBINING CARON

# COMBINING CEDILLA


$string = v99.780.807
# LATIN SMALL LETTER C

# COMBINING CEDILLA
# COMBINING CARON

标准化函数可以对它们重新安排成可靠的顺序。这样的函数有一些,包括进行标准分解的函数NFD( )跟标准分解后再进行标准组合的NFC函数。不管使用了上面3种方法中的哪一种来表示字符,它的NFD版本是v99.807.780,NFC版本是v231.780。


有时你可能更喜欢用NFKD( ) 跟 NFKC( ), 它们跟前面提到的NFD,NFC是类似的, 只是在分解的时候采用的是兼容分解(compatible decomposition)而不是标准分解,NFKC在组合的时候还是继续采用标准组合。举个例子,\x{FB00} 表示的是2个f联结在一起的字符(the double-f ligature)。它的NFD and NFC 格式是一样的:"\x{FB00}", 但是它的NFKD跟NFKC格式却是包含2个字符的字符串: "\x{66}\x{66}".


1.2.4 参考


参考本章开头的字符编码一节,有关unicode::normalize模块的资料,在菜单8.20中

阅读(472) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~