pinyin4j學習筆記

 最近在倒騰與搜索相關的拼音檢查技術,順便看了一下中文轉拼音開源插件pinyin4j的源碼,參考資料:http://blog.csdn.net/hfhwfw/archive/2010/11/23/6030816.aspx整理了一下筆記:

pinyin4j是一個支持將簡體和繁體中文轉換到成拼音的Java開源類庫,作者是Li Min ([email protected])。

1. pinyin4j的官方下載地址:http://sourceforge.net/projects/pinyin4j/files/,目前最新的版本是2.5.0

2. 下載解壓後的目錄結構及說明如下

  • doc : pinyin4j的api文檔
  • lib : pinyin4j的jar包
  • src : pinyin4j的源代碼
  • CHANGELOG.txt : pinyin4j的版本更新日誌
  • COPYING.txt : LICENSE說明
  • README.txt : pinyin4j的概要介紹

3.   源碼解析

     net/sourceforge/pinyin4j

                            ChineseToPinyinResource:讀取/pinyindb/unicode_to_hanyu_pinyin.txt

                            GwoyeuRomatzyhResource:讀取/pinyindb/pinyin_gwoeu_mapping.xml

                            GwoyeuRomatzyhTranslator:漢語拼音轉換爲Gwoyeu拼音

                            PinyinRomanizationResource:讀取/pinyindb/pinyin_mapping.xml

                            PinyinRomanizationType:定義漢語拼音的六種類型(pinyin4j支持將漢字轉化成六種拼音表示法。其對應關係是:漢語拼音-Hanyu Pinyin,通用拼音-Tongyong Pinyin, 威妥瑪拼音(威瑪拼法)-Wade-Giles  Pinyin, 注音符號第二式-MPSII Pinyin, 耶魯拼法-Yale Pinyin和國語羅馬字-Gwoyeu Romatzyh)

                            PinyinRomanizationTranslator:拼音轉換,convertRomanizationSystem(源拼音字符串,源拼音類型,目標拼音類型)

                            PinyinFormatter:漢語拼音格式化(如:根據提供的格式格式化拼音字符串;注音標等方法)

                            PinyinHelper:音標格式化方法類(六種拼音類型的獲取方法等)

                            ResourceHelper:從classpath路徑下讀取文件流BufferedInputStream

                            TextHelper:獲取漢語拼音中拼音或音調數字

                                        extractToneNumber返回音調數字,如輸入:luan4 返回:4  

                                        extractPinyinString返回漢語拼音前的拼音,如輸入:luan4 返回:luan

                            /format

                                  HanyuPinyinCaseType:定義漢語拼音大小寫類型(控制生成的拼音是以大寫方式顯示還是以小寫方式顯示) 

  • LOWERCASE :guó
  • UPPERCASE :GUÓ

                                  HanyuPinyinToneType:定義漢語拼音聲調類型   

  • WITH_TONE_NUMBER(以數字代替聲調) :  zhong1  zhong4
  • WITHOUT_TONE (無聲調) :             zhong   zhong
  • WITH_TONE_MARK (有聲調) :           zhōng  zhòng

                                  HanyuPinyinVCharType:定義漢語拼音字符u的類型(碰到unicode 的ü 、v 和 u時的顯示方式) 

  • WITH_U_AND_COLON : lu:3
  • WITH_V :            lv3
  • WITH_U_UNICODE :    lü3

                                  HanyuPinyinOutputFormat:拼音格式類型構造類

                                  /exception  異常類

                                      BadHanyuPinyinOutputFormatCombination:拼音格式化組合錯誤異常,如一下組合:

                                          LOWERCASE-WITH_V-WITH_TONE_MARK   LOWERCASE-WITH_U_UNICODE-WITH_TONE_MARK

                                          UPPERCASE-WITH_V-WITH_TONE_MARK   UPPERCASE-WITH_U_UNICODE-WITH_TONE_MARK

其主要思路:

     1)先通過漢字字符的unicode編碼從unicode_to_hanyu_pinyin.txt找到對應的帶聲調數字的拼音

     2)根據給定的輸出格式化要求對該帶聲調的數字拼音進行格式化處理

     3)在各個拼音之間可以相互轉換:

          根據pinyin_mapping.xml可以找到漢語拼音對應其他四種格式,如:

 <item>
  <Hanyu>a</Hanyu>
  <Wade>a</Wade>
  <MPSII>a</MPSII>
  <Yale>a</Yale>
  <Tongyong>a</Tongyong>
 </item>

根據pinin_gwoyeu_mapping.xml可以找出漢語拼音與Gwoyeu不同聲調對應的格式,如:

 <item>
  <Hanyu>a</Hanyu>
  <Gwoyeu_I>a</Gwoyeu_I>
  <Gwoyeu_II>ar</Gwoyeu_II>
  <Gwoyeu_III>aa</Gwoyeu_III>
  <Gwoyeu_IV>ah</Gwoyeu_IV>
  <Gwoyeu_V>.a</Gwoyeu_V>
 </item>

4.  字符串轉化成拼音Java代碼示例

代碼:

import java.util.HashSet;
import java.util.Set;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
public class Pinyin4j {
public static Set<String> getPinyin(String src){
if(src != null && !src.trim().equalsIgnoreCase("")){
char[] srcChar;
srcChar = src.toCharArray();
//漢語拼音格式輸出類
HanyuPinyinOutputFormat hanYuPinOutputFormat = new HanyuPinyinOutputFormat();
//輸出設置,大小寫,音標方式等
hanYuPinOutputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); //小寫
hanYuPinOutputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); //無音調
hanYuPinOutputFormat.setVCharType(HanyuPinyinVCharType.WITH_V); //'¨¹' is "v"
String[][] temp = new String[src.length()][];
for(int i=0;i<srcChar.length;i++){
char c = srcChar[i];
//是中文或者a-z或者A-Z轉換拼音(我的需求,是保留中文或者a-z或者A-Z)
if(String.valueOf(c).matches("[//u4E00-//u9FA5]+")){ //中文字符
try{
temp[i] = PinyinHelper.toHanyuPinyinStringArray(srcChar[i],hanYuPinOutputFormat);
}catch(BadHanyuPinyinOutputFormatCombination e){
e.printStackTrace();
}
}else if(((int)c>=65&&(int)c<=90)||((int)c>=97&&(int)c<=122)){ //英文字母
temp[i] = new String[]{String.valueOf(srcChar[i])};
}else{ //其他字符
temp[i] = new String[]{""};
}
}
String[] pinyinArray = ExChange(temp);
Set<String> pinyinSet = new HashSet<String>();
for(int i=0;i<pinyinArray.length;i++){
pinyinSet.add(pinyinArray[i]);
}
return pinyinSet;
}
return null;
}
/**
* 字符串集合轉換字符串(逗號分隔)
* @param stringSet
* @return
*/

public static String makeStringByStringSet(Set<String> stringSet,String separator){
StringBuilder str = new StringBuilder();
int i=0;
for(String s :stringSet){
if(i == stringSet.size() - 1){
str.append(s);
}else{
str.append(s+separator);
}
i++;
}
return str.toString().toLowerCase();
}
private static String[] ExChange(String[][] strJaggedArray) {
String[][] temp = DoExchange(strJaggedArray);
return temp[0];
}
private static String[][] DoExchange(String[][] strJaggedArray) {
int len = strJaggedArray.length;
if(len >= 2){
int len1 = strJaggedArray[0].length;
int len2 = strJaggedArray[1].length;
int newlen = len1*len2;
String[] temp = new String[newlen];
int index = 0;
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
temp[index] = strJaggedArray[0][i]+strJaggedArray[1][j];
index++;
}
}
String[][] newArray = new String[len-1][];
for(int i=2;i<len;i++){
newArray[i-1] = strJaggedArray[i];
}
newArray[0] = temp;
return DoExchange(newArray);
}else{
return strJaggedArray;
}
}
/**
* 只轉換漢字爲拼音,其他字符不變
* @param src
* @return
*/

public static String getPinyinWithMark(String src){
if(src != null && !src.trim().equalsIgnoreCase("")){
char[] srcChar;
srcChar = src.toCharArray();
//漢語拼音格式輸出類
HanyuPinyinOutputFormat hanYuPinOutputFormat = new HanyuPinyinOutputFormat();
//輸出設置,大小寫,音標方式等
hanYuPinOutputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); //小寫
hanYuPinOutputFormat.setToneType(HanyuPinyinToneType.WITH_TONE_MARK); //無音調
hanYuPinOutputFormat.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE); //'¨¹' is "v"
StringBuffer output = new StringBuffer();
//String[][] temp = new String[src.length()][];
for(int i=0;i<srcChar.length;i++){
char c = srcChar[i];
//是中文轉換拼音(我的需求,是保留中文)
if(String.valueOf(c).matches("[//u4E00-//u9FA5]+")){ //中文字符
try{
String[] temp = PinyinHelper.toHanyuPinyinStringArray(srcChar[i],hanYuPinOutputFormat);
output.append(temp[0]);
output.append(" ");
}catch(BadHanyuPinyinOutputFormatCombination e){
e.printStackTrace();
}
}else{ //其他字符
output.append(String.valueOf(srcChar[i]));
}
}
return output.toString();
}
return null;
}
/**
* 只轉換漢字爲拼音,其他字符不變
* @param src
* @return
*/

public static String getPinyinWithMark2(String inputString){
//漢語拼音格式輸出類
HanyuPinyinOutputFormat hanYuPinOutputFormat = new HanyuPinyinOutputFormat();
//輸出設置,大小寫,音標方式等
hanYuPinOutputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); //小寫
hanYuPinOutputFormat.setToneType(HanyuPinyinToneType.WITH_TONE_MARK); //有音調
hanYuPinOutputFormat.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE); //'¨¹' is "u:"
char[] input = inputString.trim().toCharArray();
StringBuffer output = new StringBuffer();
for(int i=0;i<input.length;i++){
//是中文轉換拼音(我的需求,是保留中文)
if(Character.toString(input[i]).matches("[//u4E00-//u9FA5]+")){ //中文字符
try{
String[] temp = PinyinHelper.toHanyuPinyinStringArray(input[i],hanYuPinOutputFormat);
output.append(temp[0]);
output.append(" ");
}catch(BadHanyuPinyinOutputFormatCombination e){
e.printStackTrace();
}
}else{ //其他字符
output.append(Character.toString(input[i]));
}
}
return output.toString();
}
/**
* @param args
*/

public static void main(String[] args) {
String str = "我是中國人! I'm Chinese!"
//System.out.println(makeStringByStringSet(getPinyin(str)," "));
System.out.println(getPinyinWithMark2(str)+'ŏ');
}
}
附件:

1.各種拼音說明

Yale Pinyin是在第二次世界大戰期間由美國軍方發明的編碼系統,主要爲了讓在中國地區作戰的美軍士兵能夠快速地熟悉漢語發音,能夠向當地人請求幫助,可以說這是一個速成教材,它的目的甚至不是用來互相交流而是使士兵在發音時不會被中國人聽錯就可以了。

Gwoyeu Romatzyh:即國語羅馬字,它是由林語堂提議建立的,在1928年由國民政府大學堂頒佈推行。在中國的臺灣省這一編碼體系得到了保留,但是它就像 Yale一樣現在幾乎很少有人使用,在1986年,國語羅馬字被國語注音符號第二式(MPSII)所取代,在2002年,又被通用拼音(Tongyong Pinyin)取代,成爲臺灣今天正式的官方漢語音譯編碼體系。

威妥瑪拼音,習慣稱作威妥瑪拼法或威瑪式拼音、韋氏拼音、威翟式拼音,是一套用於拼寫中文普通話的羅馬拼音系統。19世紀中葉由英國人威妥瑪(Thomas Francis Wade)發明,後由翟理斯(Herbert Allen Giles)完成修訂,並編入其所撰寫的漢英字典。

 

參考資料:

1.       pinyin4j的官方資料 http://pinyin4j.sourceforge.net/

2.       漢語言的羅馬化 http://icookies.spaces.live.com/blog/cns!2CC37E2F87FB3864!170.entry

3.       Wiki: 威妥瑪拼音(維基百科) http://wapedia.mobi/zh/%E5%A8%81%E5%A6%A5%E7%8E%9B%E6%8B%BC%E9%9F%B3

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章