Skip to content

Commit

Permalink
fix(3.6.2): 修复 surname 模式和 customPinyin 同时使用的问题
Browse files Browse the repository at this point in the history
fix(3.6.2): 修复 surname 模式和 customPinyin 同时使用的问题
  • Loading branch information
zh-lx authored Jan 8, 2022
2 parents 71c00f8 + 8fe7df6 commit 3644d84
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 86 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 3.6.2

当前版本: 3.6.1 -> 3.6.2

- 问题修复
- 修复 `customPinyin``surname` 同时使用时没有优先匹配自定义拼音的问题
- 修复 `surname` 模式下部分情况姓氏拼音匹配不正确的问题

## 3.6.1

当前版本: 3.6.0 -> 3.6.1
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@

## 版本更新

当前版本: 3.6.0 -> 3.6.1
当前版本: 3.6.1 -> 3.6.2

- 问题修复
- 修复 `removeNonZh` 参数为 `true` 且输入字符串全部为非汉字时的堆栈溢出问题
- 修复 `customPinyin``surname` 同时使用时没有优先匹配自定义拼音的问题
- 修复 `surname` 模式下部分情况姓氏拼音匹配不正确的问题

点击查看 [版本更新文档](./CHANGELOG.md)

Expand Down
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/pinyin-pro.js

Large diffs are not rendered by default.

41 changes: 19 additions & 22 deletions lib/custom.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
import _DICT1 from '../data/dict1';
import _DICT2 from '../data/dict2';
import _DICT3 from '../data/dict3';
import _DICT4 from '../data/dict4';
import _DICT5 from '../data/dict5';
const _dictArr = [{}, {}, _DICT2, _DICT3, _DICT4, _DICT5];
let customDict: { [key: string]: string } = {};

/**
* @description: 用户自定义拼音
* @param {{ [key: string]: string }} config 用户自定义的拼音映射(支持汉字、词语、句子的映射),若匹配到该映射,优先将汉字转换为该映射
*/
export function customPinyin(config: { [key: string]: string } = {}) {
for (let key in config) {
let pinyin = config[key];
if (key.length === 1) {
const wordCode = key.charCodeAt(0);
_DICT1[wordCode] = pinyin;
} else if (key.length === 2) {
_dictArr[2][key] = pinyin;
} else if (key.length === 3) {
_dictArr[3][key] = pinyin;
} else if (key.length === 4) {
_dictArr[4][key] = pinyin;
} else {
_dictArr[5][key] = pinyin;
customDict = {};
const keys = Object.keys(config).sort(
(key1, key2) => key2.length - key1.length
);
keys.forEach((key) => {
customDict[key] = config[key];
});
}

export const getCustomDict = () => {
return customDict;
};

export function hasCustomConfig() {
for (let key in customDict) {
if (key) {
return true;
}
}
return false;
}

export const DICT1 = _DICT1;
export const dictArr = _dictArr;
70 changes: 63 additions & 7 deletions lib/handle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import INITIAL_LIST from '../data/initial';
import Surnames from '../data/surname';
import { DICT1, dictArr } from './custom';
import { getCustomDict } from './custom';
import DICT1 from '../data/dict1';
import DICT2 from '../data/dict2';
import DICT3 from '../data/dict3';
import DICT4 from '../data/dict4';
import DICT5 from '../data/dict5';
const dictArr = [{}, {}, DICT2, DICT3, DICT4, DICT5];

/**
* @description: 获取单个字符的拼音
Expand All @@ -25,11 +31,23 @@ const getSingleWordPinyin: GetSingleWordPinyin = (word) => {
type GetPinYin = (
word: string,
length: number,
mode?: 'normal' | 'surname'
params?: {
mode?: 'normal' | 'surname';
useCustomConfig?: boolean;
}
) => string;
const getPinyin: GetPinYin = (word, length, mode = 'normal') => {
const getPinyin: GetPinYin = (
word,
length,
params = { mode: 'normal', useCustomConfig: false }
) => {
// 如果有用户自定拼音,则优先使用自定义拼音
if (params?.useCustomConfig) {
return getCustomPinyin(word, params?.mode);
}

// 如果是姓氏模式,则优先替换姓氏拼音
if (mode === 'surname') {
if (params?.mode === 'surname') {
return getSurnamePinyin(word);
}

Expand Down Expand Up @@ -86,23 +104,61 @@ const getSurnamePinyin: GetSurnamePinyin = (word) => {
let index = _word.indexOf(key);
if (index > -1) {
const left_word = word.slice(0, index);
// left_word 存在时,说明左侧不存在姓氏词
// 取出该词后左边拼音
const left_pinyin = left_word
? `${getPinyin(left_word, left_word.length)} `
? `${getPinyin(left_word, left_word.length, { mode: 'surname' })} `
: '';
// 取出该词后右边拼音
const right_word = word.slice(index + key.length);
const right_pinyin = right_word
? ` ${getPinyin(right_word, right_word.length, 'surname')}`
? ` ${getPinyin(right_word, right_word.length, { mode: 'surname' })}`
: '';
// 取出的词的拼音
const word_pinyin = Surnames[key];
return `${left_pinyin}${word_pinyin}${right_pinyin}`;
}
}
// 若姓氏表中的词均为匹配成功,则使用常规匹配
return getPinyin(word, word.length);
};

/**
* @description: 有自定义拼音优先匹配自定义拼音
* @param {string} word
* @param {string} mode
* @return {string}
*/
type GetCustomPinyin = (word: string, mode?: 'normal' | 'surname') => string;
const getCustomPinyin: GetCustomPinyin = (word, mode = 'normal') => {
const customDict = getCustomDict();
let _word = word;
for (let key in customDict) {
let index = _word.indexOf(key);
if (index > -1) {
const left_word = word.slice(0, index);
// 取出该词后左边拼音
const left_pinyin = left_word
? `${getPinyin(left_word, left_word.length, {
mode,
useCustomConfig: true,
})} `
: '';
// 取出该词后右边拼音
const right_word = word.slice(index + key.length);
const right_pinyin = right_word
? ` ${getPinyin(right_word, right_word.length, {
mode,
useCustomConfig: true,
})}`
: '';
// 取出的词的拼音
const word_pinyin = customDict[key];
return `${left_pinyin}${word_pinyin}${right_pinyin}`;
}
}
return getPinyin(word, word.length, { mode });
};

/**
* @description: 将带音调符号拼音转换为不带音调拼音
* @param {string} pinyin
Expand Down
6 changes: 5 additions & 1 deletion lib/pinyin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
getPinyinWithNum,
getFirstLetter,
} from './handle';
import { hasCustomConfig } from './custom';

interface BasicOptions {
toneType?: 'symbol' | 'num' | 'none';
Expand Down Expand Up @@ -81,7 +82,10 @@ function pinyin(word: string, options = DEFAULT_OPTIONS): string | string[] {
}

// 获取原始拼音
let pinyin = getPinyin(word, word.length, options.mode);
let pinyin = getPinyin(word, word.length, {
mode: options.mode,
useCustomConfig: hasCustomConfig(),
});

// 对multiple进行处理
if (word.length === 1 && options.multiple) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pinyin-pro",
"version": "3.6.1",
"version": "3.6.2",
"description": "汉字转拼音库。获取中文拼音、韵母、声母、声调、首字母,支持拼音匹配",
"main": "./dist/index.js",
"typings": "./types/lib/index.d.ts",
Expand Down
114 changes: 68 additions & 46 deletions test/dist.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,53 +269,10 @@ describe('surname', () => {
const result = pinyin('我叫令狐冲', { mode: 'surname' });
expect(result).to.be.equal('wǒ jiào líng hú chōng');
});
});

describe('customConfig', () => {
it('custom none', () => {
customPinyin();
const result = pinyin('干一行行一行');
expect(result).to.be.equal('gān yī xíng xíng yī xíng');
});

it('custom1', () => {
customPinyin({
: 'nài',
});
const result = pinyin('我姓能');
expect(result).to.be.equal('wǒ xìng nài');
});

it('custom2', () => {
customPinyin({
好好: 'hào hǎo',
});
const result = pinyin('爱好好多');
expect(result).to.be.equal('ài hào hǎo duō');
});

it('custom3', () => {
customPinyin({
哈什玛: 'hà shén mǎ',
});
const result = pinyin('哈什玛');
expect(result).to.be.equal('hà shén mǎ');
});

it('custom4', () => {
customPinyin({
暴虎冯河: 'bào hǔ píng hé',
});
const result = pinyin('暴虎冯河');
expect(result).to.be.equal('bào hǔ píng hé');
});

it('custom>5', () => {
customPinyin({
干一行行一行: 'gàn yī háng xíng yī háng',
});
const result = pinyin('干一行行一行');
expect(result).to.be.equal('gàn yī háng xíng yī háng');
it('multiple surname2', () => {
const result = pinyin('曾令狐冲', { mode: 'surname' });
expect(result).to.be.equal('zēng líng hú chōng');
});
});

Expand Down Expand Up @@ -463,3 +420,68 @@ describe('removeNonZh', () => {
expect(result).to.be.equal('');
});
});

describe('customConfig', () => {
it('custom none', () => {
customPinyin();
const result = pinyin('干一行行一行');
expect(result).to.be.equal('gān yī xíng xíng yī xíng');
});

it('custom1', () => {
customPinyin({
: 'nài',
});
const result = pinyin('我姓能');
expect(result).to.be.equal('wǒ xìng nài');
});

it('custom2', () => {
customPinyin({
好好: 'hào hǎo',
});
const result = pinyin('爱好好多');
expect(result).to.be.equal('ài hào hǎo duō');
});

it('custom3', () => {
customPinyin({
哈什玛: 'hà shén mǎ',
});
const result = pinyin('哈什玛');
expect(result).to.be.equal('hà shén mǎ');
});

it('custom4', () => {
customPinyin({
暴虎冯河: 'bào hǔ píng hé',
});
const result = pinyin('暴虎冯河');
expect(result).to.be.equal('bào hǔ píng hé');
});

it('custom>5', () => {
customPinyin({
干一行行一行: 'gàn yī háng xíng yī háng',
});
const result = pinyin('干一行行一行');
expect(result).to.be.equal('gàn yī háng xíng yī háng');
});

it('custom with surname', () => {
customPinyin({
乐嘉: 'lè jiā',
});
const result = pinyin('乐嘉', { mode: 'surname' });
expect(result).to.be.equal('lè jiā');
});

it('customs', () => {
customPinyin({
: 'hào',
好好: 'hào hǎo',
});
const result = pinyin('好好');
expect(result).to.be.equal('hào hǎo');
});
});
8 changes: 4 additions & 4 deletions types/lib/custom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
export declare function customPinyin(config?: {
[key: string]: string;
}): void;
export declare const DICT1: string[];
export declare const dictArr: {
[prop: string]: string;
}[];
export declare const getCustomDict: () => {
[key: string]: string;
};
export declare function hasCustomConfig(): boolean;
5 changes: 4 additions & 1 deletion types/lib/handle.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
* @param {string} mode
* @return {string}
*/
declare type GetPinYin = (word: string, length: number, mode?: 'normal' | 'surname') => string;
declare type GetPinYin = (word: string, length: number, params?: {
mode?: 'normal' | 'surname';
useCustomConfig?: boolean;
}) => string;
declare const getPinyin: GetPinYin;
/**
* @description: 将带音调符号拼音转换为不带音调拼音
Expand Down

0 comments on commit 3644d84

Please sign in to comment.