在没有出现emoji字符之前,算字符串的长度就很简单,直接遍历字符串,找出其中的中文和其他字符直接算出长度即可。但是出现emoji之后,就没有那么简单了。
一:先介绍几个基本概念:
1 编码:计算机内部不能存储字符,只能存储数字,数字与字符或符号的对照表,就是编码(比如ascll编码)
2 UTF :即Unicode Transformation formats (Unicode 转换格式),一个字符或者符合用Unicode表示的数字。(UTF8 是一个字符用8位表示,32即32位表示)
3 码点,码元:Unicode 几乎为世界上每一种字符或者符号定义了唯一的一个数字,即码点;一个码点有时候对应一个码元,有时候多个。两个合起来的码元对应一个码元即代理对。
4 nsstring 与 Unicode:nsstring 的length是字符串中包含的码元个数。
5 nsstring 字符串中可能包含组合字符序列、代理对、变体字符序列,所以length的长度并不是你看到的。
二:判断汉字和emoj的方法
1 判断汉字
+ (BOOL)isChineseChar:(int)ch{
if( ch >=0x4e00 && ch <0x9fa5){
returnYES;
}else{
returnNO;
}
}
2 判断emoji
- (BOOL)isEmoji:(NSString*)substring
{
BOOLreturnValue =NO;
constunicharhs = [substringcharacterAtIndex:0];
// surrogate pair
if(0xd800<= hs && hs <=0xdbff) {
if(substring.length>1) {
constunicharls = [substringcharacterAtIndex:1];
constintuc = ((hs -0xd800) *0x400) + (ls -0xdc00) +0x10000;
if(0x1d000<= uc && uc <=0x1f9c0) {
returnValue =YES;
}
}
}elseif(substring.length>1) {
constunicharls = [substringcharacterAtIndex:1];
if(ls ==0x20e3) {
returnValue =YES;
}
}else{
// non surrogate
if(0x2100<= hs && hs <=0x27ff) {
returnValue =YES;
}elseif(0x2B05<= hs && hs <=0x2b07) {
returnValue =YES;
}elseif(0x2934<= hs && hs <=0x2935) {
returnValue =YES;
}elseif(0x3297<= hs && hs <=0x3299) {
returnValue =YES;
}elseif(hs ==0xa9|| hs ==0xae|| hs ==0x303d|| hs ==0x3030|| hs ==0x2b55|| hs ==0x2b1c|| hs ==0x2b1b|| hs ==0x2b50) {
returnValue =YES;
}
}
return returnValue;
}
至于其他的字符我都归为一类了。
计算字符的长度
- (NSInteger)numberOfString:(NSString*)str
{
if(![str isNotEmpty])
{
return0;
}
__block NSInteger characterNum =0;
[str enumerateSubstringsInRange:NSMakeRange(0, str.length)
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString*_Nullablesubstring,NSRangesubstringRange,NSRangeenclosingRange,BOOL*_Nonnullstop) {
if([[selfclass]isChineseChar:[substring characterAtIndex:0]])
{
characterNum +=2;
}elseif([self isEmoji:substring])
{
characterNum +=2;
}else
{
characterNum ++;
}
}];
returncharacterNum;
}
参考:https://www.objccn.io/issue-9-1/
http://stackoverflow.com/questions/19886642/check-if-there-is-an-emoji-contained-in-a-string