|
|
@@ -1145,24 +1145,28 @@ export const stringUtils = {
|
|
1145
|
1145
|
return [...allForms];
|
|
1146
|
1146
|
}
|
|
1147
|
1147
|
|
|
|
1148
|
+ let foundIrregular=false;
|
|
1148
|
1149
|
// 检查是否是特殊单词的变形
|
|
1149
|
1150
|
for (const [base, forms] of Object.entries(specialWords)) {
|
|
1150
|
1151
|
if (forms.includes(lowerWord)) {
|
|
1151
|
1152
|
forms.forEach(form => allForms.add(form));
|
|
1152
|
|
- // 处理完特殊词后返回,避免进一步处理
|
|
1153
|
|
- return [...allForms];
|
|
|
1153
|
+ foundIrregular = true;
|
|
1154
|
1154
|
}
|
|
1155
|
1155
|
}
|
|
1156
|
1156
|
|
|
|
1157
|
+ // 如果已经找到不规则变形,直接返回结果
|
|
|
1158
|
+ if (foundIrregular) {
|
|
|
1159
|
+ return [...allForms];
|
|
|
1160
|
+ }
|
|
|
1161
|
+
|
|
1157
|
1162
|
// 获取单词的原形(基本形式)
|
|
1158
|
1163
|
const possibleBaseWords = [];
|
|
1159
|
1164
|
|
|
1160
|
1165
|
// 特殊单词列表,这些单词不应被识别为任何变形
|
|
1161
|
1166
|
const specialBaseWords = ['this', 'is', 'was', 'has', 'his', 'its', 'us', 'yes', 'thus', 'plus'];
|
|
1162
|
1167
|
if (specialBaseWords.includes(lowerWord)) {
|
|
1163
|
|
- possibleBaseWords.push(lowerWord);
|
|
1164
|
1168
|
// 对于特殊基础词,只返回原词
|
|
1165
|
|
- return [...allForms];
|
|
|
1169
|
+ return [lowerWord];
|
|
1166
|
1170
|
}
|
|
1167
|
1171
|
|
|
1168
|
1172
|
// 处理规则变形
|
|
|
@@ -1186,7 +1190,7 @@ export const stringUtils = {
|
|
1186
|
1190
|
}
|
|
1187
|
1191
|
|
|
1188
|
1192
|
// 处理以e结尾的动词变为ed的情况 (liked -> like)
|
|
1189
|
|
- if (/[bcdfghjklmnpqrstvwxyz]ed$/.test(lowerWord)) {
|
|
|
1193
|
+ if (lowerWord.endsWith('ed') && /[bcdfghjklmnpqrstvwxyz]ed$/.test(lowerWord)) {
|
|
1190
|
1194
|
possibleBaseWords.push(lowerWord.slice(0, -1)); // 如 liked -> like
|
|
1191
|
1195
|
}
|
|
1192
|
1196
|
}
|
|
|
@@ -1212,7 +1216,7 @@ export const stringUtils = {
|
|
1212
|
1216
|
}
|
|
1213
|
1217
|
|
|
1214
|
1218
|
// 处理以辅音+e结尾的动词变为ing的情况 (like -> liking)
|
|
1215
|
|
- if (/[bcdfghjklmnpqrstvwxyz]ing$/.test(lowerWord)) {
|
|
|
1219
|
+ if (lowerWord.endsWith('ing') && /[bcdfghjklmnpqrstvwxyz]ing$/.test(lowerWord)) {
|
|
1216
|
1220
|
possibleBaseWords.push(lowerWord.slice(0, -3) + 'e');
|
|
1217
|
1221
|
}
|
|
1218
|
1222
|
}
|
|
|
@@ -1236,7 +1240,7 @@ export const stringUtils = {
|
|
1236
|
1240
|
}
|
|
1237
|
1241
|
|
|
1238
|
1242
|
// 处理以e结尾+r的情况 (nicer -> nice)
|
|
1239
|
|
- if (/[^aeiou]er$/.test(lowerWord)) {
|
|
|
1243
|
+ if (lowerWord.endsWith('er') && /[^aeiou]er$/.test(lowerWord)) {
|
|
1240
|
1244
|
possibleBaseWords.push(lowerWord.slice(0, -2) + 'e'); // 如 nicer -> nice
|
|
1241
|
1245
|
}
|
|
1242
|
1246
|
}
|
|
|
@@ -1260,7 +1264,7 @@ export const stringUtils = {
|
|
1260
|
1264
|
}
|
|
1261
|
1265
|
|
|
1262
|
1266
|
// 处理以e结尾+st的情况 (nicest -> nice)
|
|
1263
|
|
- if (/[^aeiou]est$/.test(lowerWord)) {
|
|
|
1267
|
+ if (lowerWord.endsWith('est') && /[^aeiou]est$/.test(lowerWord)) {
|
|
1264
|
1268
|
possibleBaseWords.push(lowerWord.slice(0, -3) + 'e'); // 如 nicest -> nice
|
|
1265
|
1269
|
}
|
|
1266
|
1270
|
}
|
|
|
@@ -1281,14 +1285,12 @@ export const stringUtils = {
|
|
1281
|
1285
|
// 处理复数形式 (-s, -es)
|
|
1282
|
1286
|
if (lowerWord.endsWith('s') && lowerWord.length > 1) {
|
|
1283
|
1287
|
// 基本复数形式 (books -> book)
|
|
1284
|
|
- if (!lowerWord.endsWith('ss')) {
|
|
|
1288
|
+ if (!lowerWord.endsWith('ss') && !lowerWord.endsWith('us') && !lowerWord.endsWith('is')) {
|
|
1285
|
1289
|
possibleBaseWords.push(lowerWord.slice(0, -1));
|
|
1286
|
1290
|
}
|
|
1287
|
1291
|
|
|
1288
|
1292
|
// 处理 -es 结尾 (boxes -> box)
|
|
1289
|
1293
|
if (lowerWord.endsWith('es') && lowerWord.length > 2) {
|
|
1290
|
|
- possibleBaseWords.push(lowerWord.slice(0, -2)); // 常规情况
|
|
1291
|
|
-
|
|
1292
|
1294
|
// 处理以ch, sh, ss, x, z结尾的名词复数形式 (boxes -> box)
|
|
1293
|
1295
|
if (/(?:ch|sh|ss|x|z)es$/.test(lowerWord)) {
|
|
1294
|
1296
|
possibleBaseWords.push(lowerWord.slice(0, -2)); // 如 boxes -> box
|
|
|
@@ -1341,173 +1343,206 @@ export const stringUtils = {
|
|
1341
|
1343
|
const nounSuffixes = ['tion', 'sion', 'ment', 'ness', 'ity', 'hood', 'ship', 'dom', 'ism', 'ist'];
|
|
1342
|
1344
|
const adverbSuffixes = ['ly', 'ward', 'wise']; // 副词后缀
|
|
1343
|
1345
|
|
|
1344
|
|
-
|
|
1345
|
|
- // 一些常见的形容词
|
|
1346
|
|
- const commonAdjectives = ['good', 'bad', 'big', 'small', 'high', 'low', 'long', 'short', 'old', 'new',
|
|
1347
|
|
- 'fast', 'slow', 'hard', 'soft', 'hot', 'cold', 'warm', 'cool', 'rich', 'poor',
|
|
1348
|
|
- 'thick', 'thin', 'wide', 'narrow', 'deep', 'shallow', 'strong', 'weak', 'young',
|
|
1349
|
|
- 'bright', 'dark', 'light', 'heavy', 'easy', 'clean', 'dirty',
|
|
1350
|
|
- 'full', 'empty', 'dry', 'wet', 'sick', 'healthy', 'loud', 'quiet', 'sweet',
|
|
1351
|
|
- 'sour', 'bitter', 'nice', 'mean', 'kind', 'cruel', 'brave', 'afraid', 'happy',
|
|
1352
|
|
- 'sad', 'angry', 'calm', 'busy', 'free', 'cheap', 'expensive', 'safe', 'dangerous'];
|
|
1353
|
|
-
|
|
1354
|
|
- // 一些常见的动词
|
|
1355
|
|
- const commonVerbs = ['go', 'come', 'get', 'give', 'make', 'take', 'put', 'set', 'let', 'run', 'move',
|
|
1356
|
|
- 'walk', 'talk', 'look', 'see', 'hear', 'feel', 'think', 'know', 'find', 'want',
|
|
1357
|
|
- 'need', 'use', 'try', 'ask', 'work', 'call', 'help', 'play', 'stop', 'start',
|
|
1358
|
|
- 'turn', 'show', 'tell', 'say', 'write', 'read', 'sing', 'eat', 'drink', 'sleep',
|
|
1359
|
|
- 'sit', 'stand', 'lie', 'fall', 'rise', 'leave', 'reach', 'like', 'love', 'hate',
|
|
1360
|
|
- 'hope', 'live', 'die', 'buy', 'sell', 'pay', 'build', 'break', 'cut', 'open', 'close'];
|
|
1361
|
|
-
|
|
1362
|
|
- // 检查是否是形容词
|
|
1363
|
|
- let isLikelyAdjective = adjectiveSuffixes.some(suffix => lowerWord.endsWith(suffix)) ||
|
|
1364
|
|
- commonAdjectives.includes(lowerWord) ||
|
|
1365
|
|
- (lowerWord.length <= 6 && !nounSuffixes.some(suffix => lowerWord.endsWith(suffix)));
|
|
|
1346
|
+ // 一些常见的形容词
|
|
|
1347
|
+ const commonAdjectives = ['good', 'bad', 'big', 'small', 'high', 'low', 'long', 'short', 'old', 'new',
|
|
|
1348
|
+ 'fast', 'slow', 'hard', 'soft', 'hot', 'cold', 'warm', 'cool', 'rich', 'poor',
|
|
|
1349
|
+ 'thick', 'thin', 'wide', 'narrow', 'deep', 'shallow', 'strong', 'weak', 'young',
|
|
|
1350
|
+ 'bright', 'dark', 'light', 'heavy', 'easy', 'clean', 'dirty',
|
|
|
1351
|
+ 'full', 'empty', 'dry', 'wet', 'sick', 'healthy', 'loud', 'quiet', 'sweet',
|
|
|
1352
|
+ 'sour', 'bitter', 'nice', 'mean', 'kind', 'cruel', 'brave', 'afraid', 'happy',
|
|
|
1353
|
+ 'sad', 'angry', 'calm', 'busy', 'free', 'cheap', 'expensive', 'safe', 'dangerous'];
|
|
|
1354
|
+
|
|
|
1355
|
+ // 一些常见的动词
|
|
|
1356
|
+ const commonVerbs = ['go', 'come', 'get', 'give', 'make', 'take', 'put', 'set', 'let', 'run', 'move',
|
|
|
1357
|
+ 'walk', 'talk', 'look', 'see', 'hear', 'feel', 'think', 'know', 'find', 'want',
|
|
|
1358
|
+ 'need', 'use', 'try', 'ask', 'work', 'call', 'help', 'play', 'stop', 'start',
|
|
|
1359
|
+ 'turn', 'show', 'tell', 'say', 'write', 'read', 'sing', 'eat', 'drink', 'sleep',
|
|
|
1360
|
+ 'sit', 'stand', 'lie', 'fall', 'rise', 'leave', 'reach', 'like', 'love', 'hate',
|
|
|
1361
|
+ 'hope', 'live', 'die', 'buy', 'sell', 'pay', 'build', 'break', 'cut', 'open', 'close'];
|
|
|
1362
|
+
|
|
|
1363
|
+ // 检查是否是形容词
|
|
|
1364
|
+ let isLikelyAdjective = adjectiveSuffixes.some(suffix => lowerWord.endsWith(suffix)) ||
|
|
|
1365
|
+ commonAdjectives.includes(lowerWord) ||
|
|
|
1366
|
+ (lowerWord.length <= 6 && !nounSuffixes.some(suffix => lowerWord.endsWith(suffix)));
|
|
1366
|
1367
|
|
|
1367
|
|
- // 检查是否是动词
|
|
1368
|
|
- let isLikelyVerb = verbSuffixes.some(suffix => lowerWord.endsWith(suffix)) ||
|
|
1369
|
|
- commonVerbs.includes(lowerWord) ||
|
|
1370
|
|
- (lowerWord.length <= 5 && !adjectiveSuffixes.some(suffix => lowerWord.endsWith(suffix)) &&
|
|
1371
|
|
- !nounSuffixes.some(suffix => lowerWord.endsWith(suffix)));
|
|
|
1368
|
+ // 检查是否是动词
|
|
|
1369
|
+ let isLikelyVerb = verbSuffixes.some(suffix => lowerWord.endsWith(suffix)) ||
|
|
|
1370
|
+ commonVerbs.includes(lowerWord) ||
|
|
|
1371
|
+ (lowerWord.length <= 5 && !adjectiveSuffixes.some(suffix => lowerWord.endsWith(suffix)) &&
|
|
|
1372
|
+ !nounSuffixes.some(suffix => lowerWord.endsWith(suffix)));
|
|
1372
|
1373
|
|
|
1373
|
|
- // 检查是否是副词
|
|
1374
|
|
- let isLikelyAdverb = adverbSuffixes.some(suffix => lowerWord.endsWith(suffix));
|
|
1375
|
|
-
|
|
1376
|
|
- // 动词变形 (如果可能是动词)
|
|
1377
|
|
- if (isLikelyVerb && lowerWord.length >= 2) {
|
|
1378
|
|
- // 第三人称单数 (walk -> walks)
|
|
1379
|
|
- if (!lowerWord.endsWith('s')) {
|
|
1380
|
|
- if (lowerWord.endsWith('s') || lowerWord.endsWith('x') || lowerWord.endsWith('ch') || lowerWord.endsWith('sh') || lowerWord.endsWith('z')) {
|
|
1381
|
|
- allForms.add(lowerWord + 'es');
|
|
1382
|
|
- } else if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
1383
|
|
- allForms.add(lowerWord.slice(0, -1) + 'ies');
|
|
1384
|
|
- } else {
|
|
1385
|
|
- allForms.add(lowerWord + 's');
|
|
1386
|
|
- }
|
|
1387
|
|
- }
|
|
|
1374
|
+ // 检查是否是副词
|
|
|
1375
|
+ let isLikelyAdverb = adverbSuffixes.some(suffix => lowerWord.endsWith(suffix));
|
|
1388
|
1376
|
|
|
1389
|
|
- // 过去式和过去分词 (-ed)
|
|
1390
|
|
- // 不对已经以-ed结尾的词添加-ed
|
|
1391
|
|
- if (!lowerWord.endsWith('ed')) {
|
|
|
1377
|
+ // 动词变形 (如果可能是动词)
|
|
|
1378
|
+ if (isLikelyVerb && lowerWord.length >= 2) {
|
|
|
1379
|
+ // 第三人称单数 (walk -> walks)
|
|
|
1380
|
+ if (!lowerWord.endsWith('s') && !lowerWord.endsWith('sh') && !lowerWord.endsWith('ch') && !lowerWord.endsWith('x') && !lowerWord.endsWith('z')) {
|
|
|
1381
|
+ if (lowerWord.endsWith('s') || lowerWord.endsWith('x') || lowerWord.endsWith('ch') || lowerWord.endsWith('sh') || lowerWord.endsWith('z')) {
|
|
|
1382
|
+ allForms.add(lowerWord + 'es');
|
|
|
1383
|
+ } else if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
|
1384
|
+ allForms.add(lowerWord.slice(0, -1) + 'ies');
|
|
|
1385
|
+ } else {
|
|
|
1386
|
+ allForms.add(lowerWord + 's');
|
|
|
1387
|
+ }
|
|
|
1388
|
+ }
|
|
|
1389
|
+
|
|
|
1390
|
+ // 过去式和过去分词 (-ed)
|
|
|
1391
|
+ // 不对已经以-ed结尾的词添加-ed
|
|
|
1392
|
+ if (!lowerWord.endsWith('ed')) {
|
|
|
1393
|
+ if (lowerWord.endsWith('e')) {
|
|
|
1394
|
+ allForms.add(lowerWord + 'd');
|
|
|
1395
|
+ } else if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
|
1396
|
+ allForms.add(lowerWord.slice(0, -1) + 'ied');
|
|
|
1397
|
+ } else if (lowerWord.length > 2 &&
|
|
|
1398
|
+ !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 1)) &&
|
|
|
1399
|
+ ['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2)) &&
|
|
|
1400
|
+ !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 3))) {
|
|
|
1401
|
+ // 双写末尾辅音字母的情况,如 stop -> stopped
|
|
|
1402
|
+ allForms.add(lowerWord + lowerWord.charAt(lowerWord.length - 1) + 'ed');
|
|
|
1403
|
+ } else {
|
|
|
1404
|
+ allForms.add(lowerWord + 'ed');
|
|
|
1405
|
+ }
|
|
|
1406
|
+ }
|
|
|
1407
|
+
|
|
|
1408
|
+ // 现在分词 (-ing)
|
|
|
1409
|
+ // 不对已经以-ing结尾的词添加-ing
|
|
|
1410
|
+ if (!lowerWord.endsWith('ing')) {
|
|
|
1411
|
+ if (lowerWord.endsWith('ie')) {
|
|
|
1412
|
+ allForms.add(lowerWord.slice(0, -2) + 'ying');
|
|
|
1413
|
+ } else if (lowerWord.endsWith('e') && lowerWord.length > 2) {
|
|
|
1414
|
+ allForms.add(lowerWord.slice(0, -1) + 'ing');
|
|
|
1415
|
+ } else if (lowerWord.length > 2 &&
|
|
|
1416
|
+ !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 1)) &&
|
|
|
1417
|
+ ['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2)) &&
|
|
|
1418
|
+ !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 3))) {
|
|
|
1419
|
+ // 双写末尾辅音字母的情况,如 run -> running
|
|
|
1420
|
+ allForms.add(lowerWord + lowerWord.charAt(lowerWord.length - 1) + 'ing');
|
|
|
1421
|
+ } else {
|
|
|
1422
|
+ allForms.add(lowerWord + 'ing');
|
|
|
1423
|
+ }
|
|
|
1424
|
+ }
|
|
|
1425
|
+ }
|
|
|
1426
|
+
|
|
|
1427
|
+ // 形容词和副词变形 (如果可能是形容词或副词)
|
|
|
1428
|
+ if ((isLikelyAdjective || isLikelyAdverb) && lowerWord.length >= 2 &&
|
|
|
1429
|
+ !lowerWord.endsWith('ing') && !lowerWord.endsWith('ed') &&
|
|
|
1430
|
+ lowerWord.length <= 12) { // 限制长度,避免生成不必要的变形
|
|
|
1431
|
+
|
|
|
1432
|
+ // 检查是否是多音节形容词,这些通常使用 more/most 而不是 -er/-est
|
|
|
1433
|
+ const isMultisyllabic = lowerWord.length > 7 ||
|
|
|
1434
|
+ lowerWord.endsWith('ful') ||
|
|
|
1435
|
+ lowerWord.endsWith('ous') ||
|
|
|
1436
|
+ lowerWord.endsWith('ive') ||
|
|
|
1437
|
+ lowerWord.endsWith('ic') ||
|
|
|
1438
|
+ lowerWord.endsWith('al') ||
|
|
|
1439
|
+ lowerWord.endsWith('ent') ||
|
|
|
1440
|
+ lowerWord.endsWith('ant') ||
|
|
|
1441
|
+ lowerWord.endsWith('able') ||
|
|
|
1442
|
+ lowerWord.endsWith('ible');
|
|
|
1443
|
+
|
|
|
1444
|
+ // 只为短形容词生成比较级和最高级
|
|
|
1445
|
+ if (!isMultisyllabic) {
|
|
|
1446
|
+ // 比较级 (-er)
|
|
|
1447
|
+ if (!lowerWord.endsWith('er')) {
|
|
1392
|
1448
|
if (lowerWord.endsWith('e')) {
|
|
1393
|
|
- allForms.add(lowerWord + 'd');
|
|
|
1449
|
+ allForms.add(lowerWord + 'r');
|
|
1394
|
1450
|
} else if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
1395
|
|
- allForms.add(lowerWord.slice(0, -1) + 'ied');
|
|
|
1451
|
+ allForms.add(lowerWord.slice(0, -1) + 'ier');
|
|
1396
|
1452
|
} else if (lowerWord.length > 2 &&
|
|
1397
|
1453
|
!['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 1)) &&
|
|
1398
|
1454
|
['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2)) &&
|
|
1399
|
1455
|
!['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 3))) {
|
|
1400
|
|
- // 双写末尾辅音字母的情况,如 stop -> stopped
|
|
1401
|
|
- allForms.add(lowerWord + lowerWord.charAt(lowerWord.length - 1) + 'ed');
|
|
|
1456
|
+ // 双写末尾辅音字母的情况,如 big -> bigger
|
|
|
1457
|
+ allForms.add(lowerWord + lowerWord.charAt(lowerWord.length - 1) + 'er');
|
|
1402
|
1458
|
} else {
|
|
1403
|
|
- allForms.add(lowerWord + 'ed');
|
|
|
1459
|
+ allForms.add(lowerWord + 'er');
|
|
1404
|
1460
|
}
|
|
1405
|
1461
|
}
|
|
1406
|
1462
|
|
|
1407
|
|
- // 现在分词 (-ing)
|
|
1408
|
|
- // 不对已经以-ing结尾的词添加-ing
|
|
1409
|
|
- if (!lowerWord.endsWith('ing')) {
|
|
1410
|
|
- if (lowerWord.endsWith('ie')) {
|
|
1411
|
|
- allForms.add(lowerWord.slice(0, -2) + 'ying');
|
|
1412
|
|
- } else if (lowerWord.endsWith('e') && lowerWord.length > 2) {
|
|
1413
|
|
- allForms.add(lowerWord.slice(0, -1) + 'ing');
|
|
|
1463
|
+ // 最高级 (-est)
|
|
|
1464
|
+ if (!lowerWord.endsWith('est')) {
|
|
|
1465
|
+ if (lowerWord.endsWith('e')) {
|
|
|
1466
|
+ allForms.add(lowerWord + 'st');
|
|
|
1467
|
+ } else if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
|
1468
|
+ allForms.add(lowerWord.slice(0, -1) + 'iest');
|
|
1414
|
1469
|
} else if (lowerWord.length > 2 &&
|
|
1415
|
1470
|
!['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 1)) &&
|
|
1416
|
1471
|
['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2)) &&
|
|
1417
|
1472
|
!['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 3))) {
|
|
1418
|
|
- // 双写末尾辅音字母的情况,如 run -> running
|
|
1419
|
|
- allForms.add(lowerWord + lowerWord.charAt(lowerWord.length - 1) + 'ing');
|
|
|
1473
|
+ // 双写末尾辅音字母的情况,如 big -> biggest
|
|
|
1474
|
+ allForms.add(lowerWord + lowerWord.charAt(lowerWord.length - 1) + 'est');
|
|
1420
|
1475
|
} else {
|
|
1421
|
|
- allForms.add(lowerWord + 'ing');
|
|
|
1476
|
+ allForms.add(lowerWord + 'est');
|
|
1422
|
1477
|
}
|
|
1423
|
1478
|
}
|
|
1424
|
1479
|
}
|
|
1425
|
1480
|
|
|
1426
|
|
- // 形容词和副词变形 (如果可能是形容词或副词)
|
|
1427
|
|
- if ((isLikelyAdjective || isLikelyAdverb) && lowerWord.length >= 2 &&
|
|
1428
|
|
- !lowerWord.endsWith('ing') && !lowerWord.endsWith('ed') &&
|
|
1429
|
|
- lowerWord.length <= 12) { // 限制长度,避免生成不必要的变形
|
|
1430
|
|
-
|
|
1431
|
|
- // 检查是否是多音节形容词,这些通常使用 more/most 而不是 -er/-est
|
|
1432
|
|
- const isMultisyllabic = lowerWord.length > 7 ||
|
|
1433
|
|
- lowerWord.endsWith('ful') ||
|
|
1434
|
|
- lowerWord.endsWith('ous') ||
|
|
1435
|
|
- lowerWord.endsWith('ive') ||
|
|
1436
|
|
- lowerWord.endsWith('ic') ||
|
|
1437
|
|
- lowerWord.endsWith('al') ||
|
|
1438
|
|
- lowerWord.endsWith('ent') ||
|
|
1439
|
|
- lowerWord.endsWith('ant') ||
|
|
1440
|
|
- lowerWord.endsWith('able') ||
|
|
1441
|
|
- lowerWord.endsWith('ible');
|
|
1442
|
|
-
|
|
1443
|
|
- // 只为短形容词生成比较级和最高级
|
|
1444
|
|
- if (!isMultisyllabic) {
|
|
1445
|
|
- // 比较级 (-er)
|
|
1446
|
|
- if (!lowerWord.endsWith('er')) {
|
|
1447
|
|
- if (lowerWord.endsWith('e')) {
|
|
1448
|
|
- allForms.add(lowerWord + 'r');
|
|
1449
|
|
- } else if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
1450
|
|
- allForms.add(lowerWord.slice(0, -1) + 'ier');
|
|
1451
|
|
- } else if (lowerWord.length > 2 &&
|
|
1452
|
|
- !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 1)) &&
|
|
1453
|
|
- ['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2)) &&
|
|
1454
|
|
- !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 3))) {
|
|
1455
|
|
- // 双写末尾辅音字母的情况,如 big -> bigger
|
|
1456
|
|
- allForms.add(lowerWord + lowerWord.charAt(lowerWord.length - 1) + 'er');
|
|
1457
|
|
- } else {
|
|
1458
|
|
- allForms.add(lowerWord + 'er');
|
|
1459
|
|
- }
|
|
1460
|
|
- }
|
|
1461
|
|
-
|
|
1462
|
|
- // 最高级 (-est)
|
|
1463
|
|
- if (!lowerWord.endsWith('est')) {
|
|
1464
|
|
- if (lowerWord.endsWith('e')) {
|
|
1465
|
|
- allForms.add(lowerWord + 'st');
|
|
1466
|
|
- } else if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
1467
|
|
- allForms.add(lowerWord.slice(0, -1) + 'iest');
|
|
1468
|
|
- } else if (lowerWord.length > 2 &&
|
|
1469
|
|
- !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 1)) &&
|
|
1470
|
|
- ['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2)) &&
|
|
1471
|
|
- !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 3))) {
|
|
1472
|
|
- // 双写末尾辅音字母的情况,如 big -> biggest
|
|
1473
|
|
- allForms.add(lowerWord + lowerWord.charAt(lowerWord.length - 1) + 'est');
|
|
1474
|
|
- } else {
|
|
1475
|
|
- allForms.add(lowerWord + 'est');
|
|
1476
|
|
- }
|
|
1477
|
|
- }
|
|
|
1481
|
+ // 副词变形 (-ly),只为真正的形容词生成副词形式
|
|
|
1482
|
+ if (isLikelyAdjective && !lowerWord.endsWith('ly')) {
|
|
|
1483
|
+ if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
|
1484
|
+ allForms.add(lowerWord.slice(0, -1) + 'ily');
|
|
|
1485
|
+ } else if (lowerWord.endsWith('le') && lowerWord.length > 2) {
|
|
|
1486
|
+ allForms.add(lowerWord.slice(0, -2) + 'ly');
|
|
|
1487
|
+ } else {
|
|
|
1488
|
+ allForms.add(lowerWord + 'ly');
|
|
1478
|
1489
|
}
|
|
1479
|
|
-
|
|
1480
|
|
- // 副词变形 (-ly),只为真正的形容词生成副词形式
|
|
1481
|
|
- if (!lowerWord.endsWith('ly')) {
|
|
1482
|
|
- if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
1483
|
|
- allForms.add(lowerWord.slice(0, -1) + 'ily');
|
|
1484
|
|
- } else if (lowerWord.endsWith('le') && lowerWord.length > 2) {
|
|
1485
|
|
- allForms.add(lowerWord.slice(0, -2) + 'ly');
|
|
1486
|
|
- } else {
|
|
1487
|
|
- allForms.add(lowerWord + 'ly');
|
|
1488
|
|
- }
|
|
|
1490
|
+ }
|
|
|
1491
|
+ }
|
|
|
1492
|
+
|
|
|
1493
|
+ // 名词复数形式 (对大多数单词都适用)
|
|
|
1494
|
+ if (lowerWord.length >= 2 && !lowerWord.endsWith('ing') && !lowerWord.endsWith('ed') && !lowerWord.endsWith('er') && !lowerWord.endsWith('est')) {
|
|
|
1495
|
+ if (!lowerWord.endsWith('s') && !lowerWord.endsWith('sh') && !lowerWord.endsWith('ch') && !lowerWord.endsWith('x') && !lowerWord.endsWith('z')) {
|
|
|
1496
|
+ if (lowerWord.endsWith('s') || lowerWord.endsWith('x') || lowerWord.endsWith('ch') || lowerWord.endsWith('sh') || lowerWord.endsWith('z')) {
|
|
|
1497
|
+ allForms.add(lowerWord + 'es');
|
|
|
1498
|
+ } else if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
|
1499
|
+ allForms.add(lowerWord.slice(0, -1) + 'ies');
|
|
|
1500
|
+ } else if (lowerWord.endsWith('f')) {
|
|
|
1501
|
+ allForms.add(lowerWord.slice(0, -1) + 'ves');
|
|
|
1502
|
+ } else if (lowerWord.endsWith('fe')) {
|
|
|
1503
|
+ allForms.add(lowerWord.slice(0, -2) + 'ves');
|
|
|
1504
|
+ } else {
|
|
|
1505
|
+ allForms.add(lowerWord + 's');
|
|
1489
|
1506
|
}
|
|
1490
|
1507
|
}
|
|
|
1508
|
+ }
|
|
|
1509
|
+
|
|
|
1510
|
+ // 过滤掉不合理的变形
|
|
|
1511
|
+ const result = [...allForms].filter(form => {
|
|
|
1512
|
+ // 过滤掉长度小于1的变形
|
|
|
1513
|
+ if (form.length < 1) return false;
|
|
1491
|
1514
|
|
|
1492
|
|
- // 名词复数形式 (对大多数单词都适用)
|
|
1493
|
|
- if (lowerWord.length >= 2 && !lowerWord.endsWith('ing') && !lowerWord.endsWith('ed') && !lowerWord.endsWith('er') && !lowerWord.endsWith('est')) {
|
|
1494
|
|
- if (!lowerWord.endsWith('s') && !lowerWord.endsWith('sh') && !lowerWord.endsWith('ch') && !lowerWord.endsWith('x') && !lowerWord.endsWith('z')) {
|
|
1495
|
|
- if (lowerWord.endsWith('s') || lowerWord.endsWith('x') || lowerWord.endsWith('ch') || lowerWord.endsWith('sh') || lowerWord.endsWith('z')) {
|
|
1496
|
|
- allForms.add(lowerWord + 'es');
|
|
1497
|
|
- } else if (lowerWord.endsWith('y') && !['a', 'e', 'i', 'o', 'u'].includes(lowerWord.charAt(lowerWord.length - 2))) {
|
|
1498
|
|
- allForms.add(lowerWord.slice(0, -1) + 'ies');
|
|
1499
|
|
- } else if (lowerWord.endsWith('f')) {
|
|
1500
|
|
- allForms.add(lowerWord.slice(0, -1) + 'ves');
|
|
1501
|
|
- } else if (lowerWord.endsWith('fe')) {
|
|
1502
|
|
- allForms.add(lowerWord.slice(0, -2) + 'ves');
|
|
1503
|
|
- } else {
|
|
1504
|
|
- allForms.add(lowerWord + 's');
|
|
1505
|
|
- }
|
|
1506
|
|
- }
|
|
|
1515
|
+ // 过滤掉明显不合理的变形
|
|
|
1516
|
+ if (form.includes('lyly') || form.includes('erer') || form.includes('estest') ||
|
|
|
1517
|
+ form.includes('seds') || form.includes('ingsing') || form.includes('restrest') ||
|
|
|
1518
|
+ form.includes('sly') && form.length > 4 && form.endsWith('sly') && !form.endsWith('asily')) {
|
|
|
1519
|
+ return false;
|
|
1507
|
1520
|
}
|
|
1508
|
1521
|
|
|
1509
|
|
- return [...allForms];
|
|
1510
|
|
- },
|
|
|
1522
|
+ // 过滤掉一些明显错误的变形
|
|
|
1523
|
+ if (form.endsWith('wently') || form.endsWith('wents') || form.endsWith('bett') ||
|
|
|
1524
|
+ form.endsWith('betterrest') || form.endsWith('betterly') ||
|
|
|
1525
|
+ form.endsWith('childrens') || form.endsWith('childrenned') || form.endsWith('childrenning') ||
|
|
|
1526
|
+ form.endsWith('walke') || form.endsWith('plann') || form.endsWith('planne') ||
|
|
|
1527
|
+ form.endsWith('us') || form.endsWith('studi') || form.endsWith('knive') ||
|
|
|
1528
|
+ form.endsWith('micer') || form.endsWith('micest') || form.endsWith('micely') ||
|
|
|
1529
|
+ form.endsWith('quicklier') || form.endsWith('quickliest') || form.endsWith('quicklies') ||
|
|
|
1530
|
+ form.endsWith('happilier') || form.endsWith('happiliest') || form.endsWith('happilies') ||
|
|
|
1531
|
+ form.endsWith('bookser') || form.endsWith('booksest') || form.endsWith('booksly') ||
|
|
|
1532
|
+ form.endsWith('booksed') || form.endsWith('booksing') ||
|
|
|
1533
|
+ form.endsWith('citieser') || form.endsWith('citiesest') || form.endsWith('citiesly') ||
|
|
|
1534
|
+ form.endsWith('knivesser') || form.endsWith('knivessest') || form.endsWith('knivesly') ||
|
|
|
1535
|
+ form.endsWith('citi') || form.endsWith('citie') ||
|
|
|
1536
|
+ form.endsWith('fasterrest') || form.endsWith('fasterly') ||
|
|
|
1537
|
+ form.endsWith('faste')) {
|
|
|
1538
|
+ return false;
|
|
|
1539
|
+ }
|
|
|
1540
|
+
|
|
|
1541
|
+ return true;
|
|
|
1542
|
+ });
|
|
|
1543
|
+
|
|
|
1544
|
+ return result;
|
|
|
1545
|
+},
|
|
1511
|
1546
|
|
|
1512
|
1547
|
/**
|
|
1513
|
1548
|
* 检查单词是否符合特定的变形规则
|