zoukankan      html  css  js  c++  java
  • 中、日、韩、英双字节字符的判断 0x80

    StringTrimUtils,使用charArray,Java内部使用unicode,不用在意编码
    java 代码

    1. public class StringTrimUtils {   
    2.    
    3.     /**  
    4.       * 截取一段字符的长度(汉、日、韩文字符长度为2),不区分中英文,如果数字不正好,则少取一个字符位  
    5.       *   
    6.       * @param str 原始字符串  
    7.       * @param specialCharsLength 截取长度(汉、日、韩文字符长度为2)  
    8.       * @return  
    9.       */   
    10.     public static String trim(String str, int specialCharsLength) {   
    11.         if (str == null || "".equals(str) || specialCharsLength < 1) {   
    12.             return "";   
    13.          }   
    14.         char[] chars = str.toCharArray();   
    15.         int charsLength = getCharsLength(chars, specialCharsLength);   
    16.         return new String(chars, 0, charsLength);   
    17.      }   
    18.    
    19.     /**  
    20.       * 获取一段字符的长度,输入长度中汉、日、韩文字符长度为2,输出长度中所有字符均长度为1  
    21.       * @param chars 一段字符  
    22.       * @param specialCharsLength 输入长度,汉、日、韩文字符长度为2  
    23.       * @return 输出长度,所有字符均长度为1  
    24.       */   
    25.     private static int getCharsLength(char[] chars, int specialCharsLength) {   
    26.         int count = 0;   
    27.         int normalCharsLength = 0;   
    28.         for (int i = 0; i < chars.length; i++) {   
    29.             int specialCharLength = getSpecialCharLength(chars[i]);   
    30.             if (count <= specialCharsLength - specialCharLength) {   
    31.                  count += specialCharLength;   
    32.                  normalCharsLength++;   
    33.              } else {   
    34.                 break;   
    35.              }   
    36.          }   
    37.         return normalCharsLength;   
    38.      }   
    39.    
    40.     /**  
    41.       * 获取字符长度:汉、日、韩文字符长度为2,ASCII码等字符长度为1  
    42.       * @param c 字符  
    43.       * @return 字符长度  
    44.       */   
    45.     private static int getSpecialCharLength(char c) {   
    46.         if (isLetter(c)) {   
    47.             return 1;   
    48.          } else {   
    49.             return 2;   
    50.          }   
    51.      }   
    52.    
    53.     /**  
    54.       * 判断一个字符是Ascill字符还是其它字符(如汉,日,韩文字符)  
    55.       *   
    56.       * @param char c, 需要判断的字符  
    57.       * @return boolean, 返回true,Ascill字符  
    58.       */   
    59.     private static boolean isLetter(char c) {   
    60.         int k = 0x80;   
    61.         return c / k == 0 ? true : false;   
    62.      }   
    63. }   



    为什么要用c/k?
    除法是向左做位移,判断最后的结果是否为0既可得出这个字节高位的第一位是1或0.

    想想,
    这里亦可以求c与k位与之后的值来判断是否为双字节字符.

    照这个思路搜到一帖
    http://topic.csdn.net/t/20040416/10/2972001.html

    StrLenEx为测试字符串长度,但为何要*ptr & 0x80 呢?? 


    short StrLenEx( char *str ) 

    char *ptr; 
    short slength = 0; 

    for( ptr = str; *ptr != '\0'; ) 

    if( *ptr & 0x80 ) 
    ptr += 2; 
    else 
    ptr ++; 

    slength++; 


    return slength; 



    StrLenEx为测试字符串长度,但为何要*ptr & 0x80 呢?? 



    为了识别双字节的字符,比如汉字或日文韩文等都是占两字节的, 每字节高位为1, 而一般西文字符只有一个字节,七位有效编码,高位为0 

    这个函数返回的是字符串的字符数,对双字节的字符只算一次 

    if( *ptr & 0x80 ) // 双字节字符 ? 
    ptr += 2; // 指针后移二位 
    else 
    ptr ++; // 指针后移一位 


    如 
    "abcdefgh" 字节数=8 字符数=8 
    "中cdefgh" 字节数=8 字符数=7 



    0x80对应的二进制代码为1000 0000,最高位为一,代表汉字.汉字编码格式通称为10格式. 
    一个汉字占2字节,但只代表一个字符


    *ptr & 0x80 
    如果表达式为真,说明 *ptr 高位为 1, 则是双字节字符

  • 相关阅读:
    【解题报告】2019正睿Day2
    如何卡SPFA
    【游记】2019国庆清北刷题营
    CF427D Match & Catch
    P2178 [NOI2015] 品酒大会
    Loj#6071. 「2017 山东一轮集训 Day5」字符串
    SP8093 JZPGYZ
    P3346 [ZJOI2015]诸神眷顾的幻想乡
    CF1037H Security
    CF932F Escape Through Leaf
  • 原文地址:https://www.cnblogs.com/duanxz/p/2841965.html
Copyright © 2011-2022 走看看