35 lines
1.2 KiB
TypeScript
35 lines
1.2 KiB
TypeScript
|
|
/**
|
||
|
|
* 生成给定函数体的函数注释。
|
||
|
|
*
|
||
|
|
* @param {RegExp} regExp - 用于匹配的正则表达式。
|
||
|
|
* @param {(text: string, match: boolean) => T} matchHandler - 处理匹配到的文本的函数。
|
||
|
|
* @param {(text: string, match: boolean) => T} [textHandler] - 处理未匹配到的文本的函数。
|
||
|
|
* @return {(str: string) => T[]} - 分词器函数。
|
||
|
|
*/
|
||
|
|
export function stringTokenizer<T>(
|
||
|
|
regExp: RegExp,
|
||
|
|
matchHandler: (text: string, match: boolean) => T,
|
||
|
|
textHandler?: (text: string, match: boolean) => T
|
||
|
|
): (str: string) => T[] {
|
||
|
|
|
||
|
|
const ifMatch = matchHandler;
|
||
|
|
const ifText = textHandler?textHandler: matchHandler;
|
||
|
|
|
||
|
|
return function (str: string) {
|
||
|
|
const result: T[] = [];
|
||
|
|
const matches = str.matchAll(regExp);
|
||
|
|
let index = 0;
|
||
|
|
for (const match of matches) {
|
||
|
|
const before = str.slice(index, match.index);
|
||
|
|
if (before) {
|
||
|
|
result.push(ifText(before, false));
|
||
|
|
}
|
||
|
|
result.push(ifMatch(match[0], true));
|
||
|
|
index = match.index! + match[0].length;
|
||
|
|
}
|
||
|
|
if (index < str.length) {
|
||
|
|
result.push(ifText(str.slice(index), false));
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
};
|
||
|
|
}
|