拼音工具類PinyinUtils

chaychan發表於2017-11-16

介紹

  最近在做好友列表的時候,仿照微信的好友列表,A-Z索引,需要用到好友名字的拼音,之前已經有封裝好拼音的工具類,但是最近發現對於一些多音字,姓氏的處理沒有做到位,比如姓氏單(shan),由於對於多音字沒有做一些處理,僅僅只是取多音字列表的第一個,所以取到的拼音是dan,所以利用空閒的時間對這個拼音的工具類進行了處理。

常見姓氏拼音

SimpleArrayMap<Character, String> surnames = new SimpleArrayMap<>(35);
        surnames.put('樂', "yue");
        surnames.put('乘', "sheng");
        surnames.put('乜', "nie");
        surnames.put('仇', "qiu");
        surnames.put('會', "gui");
        surnames.put('便', "pian");
        surnames.put('區', "ou");
        surnames.put('單', "shan");
        surnames.put('參', "shen");
        surnames.put('句', "gou");
        surnames.put('召', "shao");
        surnames.put('員', "yun");
        surnames.put('宓', "fu");
        surnames.put('弗', "fei");
        surnames.put('折', "she");
        surnames.put('曾', "zeng");
        surnames.put('樸', "piao");
        surnames.put('查', "zha");
        surnames.put('洗', "xian");
        surnames.put('蓋', "ge");
        surnames.put('祭', "zhai");
        surnames.put('種', "chong");
        surnames.put('祕', "bi");
        surnames.put('繁', "po");
        surnames.put('繆', "miao");
        surnames.put('能', "nai");
        surnames.put('蕃', "pi");
        surnames.put('覃', "qin");
        surnames.put('解', "xie");
        surnames.put('諶', "shan");
        surnames.put('適', "kuo");
        surnames.put('都', "du");
        surnames.put('阿', "e");
        surnames.put('難', "ning");
        surnames.put('黑', "he");複製程式碼

效果圖

image
image

拼音的獲取

上圖獲取的拼音內容如下:


pinyin: QINTANG

pinyin: QIULAN

pinyin: SHANDAN

pinyin: ZENGER

pinyin: #複製程式碼

可以看到姓氏的拼音是正確的,最後一個由於不是以漢字開頭,所以其拼音的內容是#

獲取拼音的方法

public static String getPinyin(String str) {
        // 設定拼音結果的格式
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);// 設定為大寫形式
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);// 不用加入聲調

        StringBuilder sb = new StringBuilder();

        char[] charArray = str.toCharArray();

        for (int i = 0; i < charArray.length; i++) {
            char c = charArray[i];

            if (Character.isWhitespace(c)) {// 如果是空格則跳過
                continue;
            }

            if (isHanZi(c)) {// 如果是漢字
                String s = "";
                try {
                    if (i == 0){
                        //如果是第一個,則使用獲取姓氏
                        s = getSurnamePinyin(String.valueOf(c));
                    }else{
                        // toHanyuPinyinStringArray 返回一個字串陣列是因為該漢字可能是多音字,此處只取第一個結果
                        s = PinyinHelper.toHanyuPinyinStringArray(c, format)[0];
                    }
                    sb.append(s);
                } catch (BadHanyuPinyinOutputFormatCombination e) {
                    e.printStackTrace();
                    sb.append(s);
                }

            } else {
                // 不是漢字
                if (i == 0) {
                    if (isEnglish(c)) {// 第一個屬於字母,則返回該字母
                        return String.valueOf(c).toUpperCase(Locale.ENGLISH);
                    }
                    return "#"; // 不是的話返回#號
                }
            }
        }

        return sb.toString();
    }複製程式碼

主要的邏輯是,將字串拆解成字元陣列,遍歷每個字元:

  1. 如果第一個是漢字,則獲取呼叫getSurnamePinyin()方法,獲取其對應的拼音,這個方法主要是對姓氏的處理;
  2. 如果第一個字元是英文,則直接返回該字元的大寫;
  3. 如果第一個字元不是漢字也不是英文,則直接返回"#"號;

如何判斷是否是漢字

    public static boolean isHanZi(char c) {
        Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+");
        Matcher matcher = pattern.matcher(String.valueOf(c));
        return matcher.matches();
    }複製程式碼

通過如上方法,使用正規表示式匹配,如果滿足,則說明是漢字,返回true。

如何判斷是否是英文

 public static boolean isEnglish(char c) {
    return String.valueOf(c).matches("^[a-zA-Z]*");
 }複製程式碼

獲取姓氏的拼音

    public static String getSurnamePinyin(CharSequence name) {
        if (name == null || name.length() == 0) return null;
        char ch = name.charAt(0);
        if (surnames.containsKey(ch)) {
            String s = surnames.get(ch);
            return s.toUpperCase(Locale.ENGLISH);
        }
        if (ch >= 0x4E00 && ch <= 0x9FA5) {
            int sp = (ch - 0x4E00) * 6;
            return pinyinTable.substring(sp, sp + 6).trim().toUpperCase(Locale.ENGLISH);
        } else {
            return String.valueOf(ch).toUpperCase(Locale.ENGLISH);
        }
    }複製程式碼

通過查詢已經儲存在map中對應姓氏的拼音

相關程式碼

PinyinUtils程式碼:

github.com/chaychan/Bl…

依賴到的jar包,pinyin4j-2.5.0.jar下載:

raw.githubusercontent.com/chaychan/Bl…

相關文章