汉字转拼音方案对比:Java、JavaScript 实现
汉字转拼音是中文应用中的常见需求。本文对比主流的实现方案。
应用场景
- 搜索联想:输入拼音匹配中文
- 姓名排序:按拼音首字母排序
- URL 生成:中文标题转拼音 URL
- 数据脱敏:姓名转拼音显示
- 输入法:拼音输入法核心
JavaScript 实现
pinyin-pro(推荐)
npm install pinyin-pro
import { pinyin } from 'pinyin-pro';
// 基本转换
pinyin('汉字转拼音');
// 'hàn zì zhuǎn pīn yīn'
// 声调模式
pinyin('汉字', { toneType: 'symbol' });
// 'hàn zì'
pinyin('汉字', { toneType: 'num' });
// 'han4 zi4'
pinyin('汉字', { toneType: 'none' });
// 'han zi'
// 首字母
pinyin('汉字转拼音', { pattern: 'first' });
// 'h z z p y'
// 不带空格
pinyin('汉字', { type: 'array' });
// ['hàn', 'zì']
// 多音字
pinyin('了', { multiple: true });
// ['le', 'liǎo']
带声调的拼音
// 获取带声调的拼音
const result = pinyin('你好世界', { toneType: 'symbol' });
// 'nǐ hǎo shì jiè'
// 获取数字声调
const numResult = pinyin('你好世界', { toneType: 'num' });
// 'ni3 hao3 shi4 jie4'
拼音匹配搜索
function pinyinMatch(text, keyword) {
const textPinyin = pinyin(text, { toneType: 'none', type: 'array' }).join('');
const keywordPinyin = pinyin(keyword, { toneType: 'none', type: 'array' }).join('');
return textPinyin.includes(keywordPinyin);
}
// 搜索匹配
pinyinMatch('张三', 'zs'); // true
pinyinMatch('李四', 'ls'); // true
pinyinMatch('王五', 'zs'); // false
Java 实现
pinyin4j
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.1</version>
</dependency>
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;
public class PinyinUtil {
// 汉字转拼音(带声调)
public static String toPinyin(String text) {
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setToneType(HanyuPinyinToneType.WITH_TONE_MARK);
format.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
StringBuilder sb = new StringBuilder();
for (char c : text.toCharArray()) {
String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(c, format);
if (pinyin != null) {
sb.append(pinyin[0]); // 取第一个读音
} else {
sb.append(c);
}
}
return sb.toString();
}
// 汉字转拼音(不带声调)
public static String toPinyinWithoutTone(String text) {
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
StringBuilder sb = new StringBuilder();
for (char c : text.toCharArray()) {
String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(c, format);
if (pinyin != null) {
sb.append(pinyin[0]);
} else {
sb.append(c);
}
}
return sb.toString();
}
// 获取首字母
public static String getFirstLetters(String text) {
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
StringBuilder sb = new StringBuilder();
for (char c : text.toCharArray()) {
String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(c, format);
if (pinyin != null) {
sb.append(pinyin[0].charAt(0));
} else {
sb.append(c);
}
}
return sb.toString();
}
}
使用示例
// 基本转换
PinyinUtil.toPinyin("汉字转拼音");
// "hàn zì zhuǎn pīn yīn"
// 不带声调
PinyinUtil.toPinyinWithoutTone("汉字转拼音");
// "han zi zhuan pin yin"
// 首字母
PinyinUtil.getFirstLetters("汉字转拼音");
// "HZZPY"
Spring Boot 集成
@Component
public class PinyinSearchService {
// 拼音搜索
public List<User> searchByName(String keyword) {
List<User> allUsers = userRepository.findAll();
return allUsers.stream()
.filter(user -> {
String namePinyin = PinyinUtil.toPinyinWithoutTone(user.getName());
String firstLetters = PinyinUtil.getFirstLetters(user.getName());
return namePinyin.contains(keyword.toLowerCase()) ||
firstLetters.equalsIgnoreCase(keyword);
})
.collect(Collectors.toList());
}
}
性能对比
| 库 | 语言 | 速度 | 内存 | 多音字支持 |
|---|---|---|---|---|
| pinyin-pro | JavaScript | 快 | 低 | ✅ |
| pinyin4j | Java | 中 | 中 | ✅ |
| TinyPinyin | Java | 最快 | 低 | 部分 |
多音字处理
多音字是最难处理的问题:
// 常见多音字
'了' → ['le', 'liǎo']
'行' → ['háng', 'xíng']
'长' → ['cháng', 'zhǎng']
'乐' → ['lè', 'yuè']
解决方案
- 词库匹配:根据词语上下文选择正确读音
- 机器学习:训练模型预测读音
- 人工校对:关键数据人工确认
拼音排序
// Java 按拼音排序
List<String> names = Arrays.asList("张三", "李四", "王五", "赵六");
names.sort((a, b) -> {
String pinyinA = PinyinUtil.toPinyinWithoutTone(a);
String pinyinB = PinyinUtil.toPinyinWithoutTone(b);
return pinyinA.compareTo(pinyinB);
});
// 排序结果:李四(lisi)、王五(wangwu)、赵六(zhaoliu)、张三(zhangsan)
拼音 URL 生成
function toPinyinUrl(title) {
return pinyin(title, {
toneType: 'none',
type: 'array'
}).join('-').toLowerCase();
}
toPinyinUrl('汉字转拼音完全指南');
// 'han-zi-zhuan-pin-yin-wan-quan-zhi-nan'
最佳实践
- 选择合适的库:JavaScript 用 pinyin-pro,Java 用 pinyin4j
- 缓存结果:拼音转换结果可以缓存
- 处理多音字:关键场景需要校对
- 性能优化:批量转换比逐字转换快
总结
汉字转拼音是中文应用的基础需求。选择合适的库,处理好多音字,可以满足大部分场景。