package com.zto.base.utils;
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;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.io.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*/
public class PinYinUtil {
//多音字
private static Map<String, List<String>> pinyinMap = new HashMap<String, List<String>>();
static {
initPinyin("duoyinzi_dic.txt");
}
/**
* 转为大写字母, 如:中国人民银行 =====>ZHONGGUORENMINYINHAN
* @author lance
* 2016年1月16日 下午4:56:07
*/
public static String convertUpper(String text){
return convert(text, HanyuPinyinCaseType.UPPERCASE, false);
}
/**
* 转为小写字母, 如:中国人民银行 =====>zhongguorenminyinhang
* @author lance
* 2016年1月16日 下午4:56:07
*/
public static String convertLower(String text){
return convert(text, HanyuPinyinCaseType.LOWERCASE, false);
}
/**
* 首字母大写, 如:中国人民银行 =====>ZhongGuoRenMinYinHang
* @author lance
* 2016年1月16日 下午5:04:11
*/
public static String converCapitalize(String text){
return convert(text, null, true);
}
/**
* 所有中文的第一个字母大写, 如:中国人民银行 =====>ZGRMYH
* @author lance
* 2016年1月17日 下午10:16:19
*/
public static String capitalizeUpperLetter(String text){
String c = converCapitalize(text);
if(StringUtils.isBlank(c)) {
return "";
}
return StringUtils.replaceAll(c, "[a-z]", "");
}
/**
* 所有中文的第一个字母大写, 如:中国人民银行 =====>zgrmyh
* @author lance
* 2016年1月17日 下午10:16:19
*/
public static String capitalizeLowerLetter(String text){
String c = capitalizeUpperLetter(text);
if(StringUtils.isBlank(c)){
return c;
}
return c.toLowerCase();
}
/**
* 获取首字母, 如:中国人民银行 =====>Z
* @author lance
* 2016年1月17日 下午10:11:57
*/
public static String firstLetter(String text){
String c = converCapitalize(text);
if(StringUtils.isBlank(c)) {
return "";
}
return StringUtils.substring(c, 0, 1);
}
/**
* 转为拼音
* @param text 待转化的中文字符
* @param caseType 转化类型, 即大写小写
* @param isCapitalize 是否首字母大写
* @author lance
* 2016年1月17日 下午10:28:05
*/
public static String convert(String text, HanyuPinyinCaseType caseType, boolean isCapitalize) {
if(StringUtils.isBlank(text)){
return "";
}
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
if(caseType != null) {
format.setCaseType(caseType);
isCapitalize = false;
}
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
format.setVCharType(HanyuPinyinVCharType.WITH_V);
char[] input = StringUtils.trimToEmpty(text).toCharArray();
StringBuilder builder = new StringBuilder();
Integer length = input.length;
try {
for (int i = 0; i < length; i++) {
char c = input[i];
if (Character.toString(c).matches("[\\u4E00-\\u9FA5]+")) {
String[] temp = PinyinHelper.toHanyuPinyinStringArray(c, format);
String pyRs = "";
if(temp.length == 1){
pyRs = temp[0];
}else {
String s = null;
List<String> keyList =null;
for (int x = 0; x < temp.length; x++) {
String py = temp[x];
if(py.contains("u:")){ //过滤 u:
py = py.replace("u:", "v");
System.out.println("filter u:"+py);
}
//检查重音词
keyList = pinyinMap.get(py);
if (i + 3 <= length) { //后向匹配2个汉字 大西洋
s = text.substring(i, i + 3);
if (keyList != null && (keyList.contains(s))) {
System.out.println("last 2 > " + py);
pyRs = py;
break;
}
}
if (i + 2 <= length) { //后向匹配 1个汉字 大西
s = text.substring(i, i + 2);
if (keyList != null && (keyList.contains(s))) {
System.out.println("last 1 > " + py);
pyRs = py;
break;
}
}
if ((i - 2 >= 0) && (i+1<=length)) { // 前向匹配2个汉字 龙固大
s = text.substring(i - 2, i+1);
if (keyList != null && (keyList.contains(s))) {
System.out.println("last 1 > " + py);
pyRs = py;
break;
}
}
if ((i - 1 >= 0) && (i+1<=length)) { // 前向匹配1个汉字 固大
s = text.substring(i - 1, i+1);
if (keyList != null && (keyList.contains(s))) {
System.out.println("last 1 > " + py);
pyRs = py;
break;
}
}
}
if(pyRs == null || pyRs.isEmpty()){
pyRs = temp[0];
}
}
if(isCapitalize) {
builder.append(StringUtils.capitalize(pyRs));
}else {
builder.append(pyRs);
}
} else {
if(isCapitalize) {
builder.append(StringUtils.capitalize(Character.toString(c)));
}else {
builder.append(Character.toString(c));
}
}
}
} catch (BadHanyuPinyinOutputFormatCombination ex) {
ex.printStackTrace();
}
return builder.toString();
}
public static void initPinyin(String fileName) {
// 读取多音字的全部拼音表;
InputStreamReader inputStreamReader = null;
try {
Resource resource = new ClassPathResource(fileName);
InputStream file = resource.getInputStream();
inputStreamReader = new InputStreamReader(file,"UTF-8");
} catch (Exception e) {
e.printStackTrace();
return;
}
BufferedReader br = new BufferedReader(inputStreamReader);
String s = null;
try {
while ((s = br.readLine()) != null) {
if (s != null) {
String[] arr = s.split("#");
String pinyin = arr[0];
String chinese = arr[1];
if(chinese!=null){
String[] strs = chinese.split(" ");
List<String> list = Arrays.asList(strs);
pinyinMap.put(pinyin, list);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// public static void main(String args[]){
// //String aa = "重庆";
// String aa = "双重保险";
// String rs = converCapitalize(aa);
// rs = capitalizeUpperLetter(aa);
// System.out.println(rs);
// }
}
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;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.io.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*/
public class PinYinUtil {
//多音字
private static Map<String, List<String>> pinyinMap = new HashMap<String, List<String>>();
static {
initPinyin("duoyinzi_dic.txt");
}
/**
* 转为大写字母, 如:中国人民银行 =====>ZHONGGUORENMINYINHAN
* @author lance
* 2016年1月16日 下午4:56:07
*/
public static String convertUpper(String text){
return convert(text, HanyuPinyinCaseType.UPPERCASE, false);
}
/**
* 转为小写字母, 如:中国人民银行 =====>zhongguorenminyinhang
* @author lance
* 2016年1月16日 下午4:56:07
*/
public static String convertLower(String text){
return convert(text, HanyuPinyinCaseType.LOWERCASE, false);
}
/**
* 首字母大写, 如:中国人民银行 =====>ZhongGuoRenMinYinHang
* @author lance
* 2016年1月16日 下午5:04:11
*/
public static String converCapitalize(String text){
return convert(text, null, true);
}
/**
* 所有中文的第一个字母大写, 如:中国人民银行 =====>ZGRMYH
* @author lance
* 2016年1月17日 下午10:16:19
*/
public static String capitalizeUpperLetter(String text){
String c = converCapitalize(text);
if(StringUtils.isBlank(c)) {
return "";
}
return StringUtils.replaceAll(c, "[a-z]", "");
}
/**
* 所有中文的第一个字母大写, 如:中国人民银行 =====>zgrmyh
* @author lance
* 2016年1月17日 下午10:16:19
*/
public static String capitalizeLowerLetter(String text){
String c = capitalizeUpperLetter(text);
if(StringUtils.isBlank(c)){
return c;
}
return c.toLowerCase();
}
/**
* 获取首字母, 如:中国人民银行 =====>Z
* @author lance
* 2016年1月17日 下午10:11:57
*/
public static String firstLetter(String text){
String c = converCapitalize(text);
if(StringUtils.isBlank(c)) {
return "";
}
return StringUtils.substring(c, 0, 1);
}
/**
* 转为拼音
* @param text 待转化的中文字符
* @param caseType 转化类型, 即大写小写
* @param isCapitalize 是否首字母大写
* @author lance
* 2016年1月17日 下午10:28:05
*/
public static String convert(String text, HanyuPinyinCaseType caseType, boolean isCapitalize) {
if(StringUtils.isBlank(text)){
return "";
}
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
if(caseType != null) {
format.setCaseType(caseType);
isCapitalize = false;
}
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
format.setVCharType(HanyuPinyinVCharType.WITH_V);
char[] input = StringUtils.trimToEmpty(text).toCharArray();
StringBuilder builder = new StringBuilder();
Integer length = input.length;
try {
for (int i = 0; i < length; i++) {
char c = input[i];
if (Character.toString(c).matches("[\\u4E00-\\u9FA5]+")) {
String[] temp = PinyinHelper.toHanyuPinyinStringArray(c, format);
String pyRs = "";
if(temp.length == 1){
pyRs = temp[0];
}else {
String s = null;
List<String> keyList =null;
for (int x = 0; x < temp.length; x++) {
String py = temp[x];
if(py.contains("u:")){ //过滤 u:
py = py.replace("u:", "v");
System.out.println("filter u:"+py);
}
//检查重音词
keyList = pinyinMap.get(py);
if (i + 3 <= length) { //后向匹配2个汉字 大西洋
s = text.substring(i, i + 3);
if (keyList != null && (keyList.contains(s))) {
System.out.println("last 2 > " + py);
pyRs = py;
break;
}
}
if (i + 2 <= length) { //后向匹配 1个汉字 大西
s = text.substring(i, i + 2);
if (keyList != null && (keyList.contains(s))) {
System.out.println("last 1 > " + py);
pyRs = py;
break;
}
}
if ((i - 2 >= 0) && (i+1<=length)) { // 前向匹配2个汉字 龙固大
s = text.substring(i - 2, i+1);
if (keyList != null && (keyList.contains(s))) {
System.out.println("last 1 > " + py);
pyRs = py;
break;
}
}
if ((i - 1 >= 0) && (i+1<=length)) { // 前向匹配1个汉字 固大
s = text.substring(i - 1, i+1);
if (keyList != null && (keyList.contains(s))) {
System.out.println("last 1 > " + py);
pyRs = py;
break;
}
}
}
if(pyRs == null || pyRs.isEmpty()){
pyRs = temp[0];
}
}
if(isCapitalize) {
builder.append(StringUtils.capitalize(pyRs));
}else {
builder.append(pyRs);
}
} else {
if(isCapitalize) {
builder.append(StringUtils.capitalize(Character.toString(c)));
}else {
builder.append(Character.toString(c));
}
}
}
} catch (BadHanyuPinyinOutputFormatCombination ex) {
ex.printStackTrace();
}
return builder.toString();
}
public static void initPinyin(String fileName) {
// 读取多音字的全部拼音表;
InputStreamReader inputStreamReader = null;
try {
Resource resource = new ClassPathResource(fileName);
InputStream file = resource.getInputStream();
inputStreamReader = new InputStreamReader(file,"UTF-8");
} catch (Exception e) {
e.printStackTrace();
return;
}
BufferedReader br = new BufferedReader(inputStreamReader);
String s = null;
try {
while ((s = br.readLine()) != null) {
if (s != null) {
String[] arr = s.split("#");
String pinyin = arr[0];
String chinese = arr[1];
if(chinese!=null){
String[] strs = chinese.split(" ");
List<String> list = Arrays.asList(strs);
pinyinMap.put(pinyin, list);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// public static void main(String args[]){
// //String aa = "重庆";
// String aa = "双重保险";
// String rs = converCapitalize(aa);
// rs = capitalizeUpperLetter(aa);
// System.out.println(rs);
// }
}