refactor(core): ♻️ 重构节点重命名脚本变量命名与文档
对 sntp-rename.js 进行代码重构,通过更具描述性的变量名(如 featureKeyword, proxyName)提高代码可读性。同时更新项目文档,明确该脚本专用于“守候网络” 节点命名,并对默认规则和使用说明进行了优化。 - 优化变量命名以更清晰地表达业务逻辑 - 更新 README 完善守候网络节点的命名说明 - 格式化代码逻辑以增强可维护性
This commit is contained in:
@@ -24,66 +24,68 @@ function operator(proxies) {
|
||||
|
||||
// 1. 初始化预处理:生成稳定的查找字典 (全大写+去空格)
|
||||
// 目的:无论节点名叫 "gtm 0.5x" 还是 "GTM0.5X",都能稳定映射
|
||||
const normalizedMap = {};
|
||||
const originalKeys = Object.keys(featureMap);
|
||||
const normalizeKey = key => key.toUpperCase().replace(/\s+/g, '');
|
||||
const escapeRegex = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
for (const key of originalKeys) {
|
||||
normalizedMap[normalizeKey(key)] = featureMap[key];
|
||||
const normalizedFeatureMap = {};
|
||||
const featureKeywords = Object.keys(featureMap);
|
||||
const normalizeFeatureKeyword = keyword => keyword.toUpperCase().replace(/\s+/g, '');
|
||||
const escapeRegexKeyword = keyword => keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
for (const featureKeyword of featureKeywords) {
|
||||
normalizedFeatureMap[normalizeFeatureKeyword(featureKeyword)] = featureMap[featureKeyword];
|
||||
}
|
||||
|
||||
// 2. 动态构建复合正则表达式 (核心引擎)
|
||||
// 按字符串长度降序排序,彻底解决 "短路匹配" (Short-Circuit) 问题
|
||||
const sortedKeys = [...originalKeys].sort((a, b) => b.length - a.length);
|
||||
const sortedFeatureKeywords = [...featureKeywords].sort(
|
||||
(firstFeatureKeyword, secondFeatureKeyword) => secondFeatureKeyword.length - firstFeatureKeyword.length
|
||||
);
|
||||
|
||||
const regexParts = sortedKeys.map(key => {
|
||||
const featureRegexParts = sortedFeatureKeywords.map(featureKeyword => {
|
||||
// 自动转义正则特殊字符 (防注入报错)
|
||||
const escapedKey = key.trim().split(/\s+/).filter(Boolean).map(escapeRegex).join('\\s*');
|
||||
const escapedKeywordPattern = featureKeyword.trim().split(/\s+/).filter(Boolean).map(escapeRegexKeyword).join('\\s*');
|
||||
|
||||
// 智能边界处理:如果关键词首尾都是字母或数字,就追加 \b 边界
|
||||
// 这样能防止配置的 "S1" 错误匹配到 "US1" 或 "TLS1.3"
|
||||
const trimmedKey = key.trim();
|
||||
if (/^[A-Za-z0-9]/.test(trimmedKey) && /[A-Za-z0-9]$/.test(trimmedKey)) {
|
||||
return `\\b${escapedKey}\\b`;
|
||||
const trimmedFeatureKeyword = featureKeyword.trim();
|
||||
if (/^[A-Za-z0-9]/.test(trimmedFeatureKeyword) && /[A-Za-z0-9]$/.test(trimmedFeatureKeyword)) {
|
||||
return `\\b${escapedKeywordPattern}\\b`;
|
||||
}
|
||||
return escapedKey;
|
||||
return escapedKeywordPattern;
|
||||
});
|
||||
|
||||
// 动态拼接出类似: /(GTM\s*0\.5x|\bAnytls\b|\bBGP\b|...)/i
|
||||
const featureRegex = new RegExp(`(${regexParts.join('|')})`, 'i');
|
||||
const featureRegex = new RegExp(`(${featureRegexParts.join('|')})`, 'i');
|
||||
|
||||
// 缓存后缀匹配正则,避免循环内重复创建
|
||||
const suffixRegex = /(\s*-\s*SNTP.*)$/i;
|
||||
|
||||
// 3. 执行节点遍历与注入
|
||||
return proxies.map(p => {
|
||||
const name = p.name;
|
||||
if (typeof name !== 'string') return p;
|
||||
return proxies.map(proxy => {
|
||||
const proxyName = proxy.name;
|
||||
if (typeof proxyName !== 'string') return proxy;
|
||||
|
||||
// A. 单次复合正则扫描提取
|
||||
const match = name.match(featureRegex);
|
||||
if (!match) return p; // 未命中配置库,直接放行
|
||||
// 单次复合正则扫描提取
|
||||
const featureMatch = proxyName.match(featureRegex);
|
||||
if (!featureMatch) return proxy; // 未命中配置库,直接放行
|
||||
|
||||
// B. 清洗提取到的特征词,并去 O(1) 字典中取值
|
||||
const mapKey = normalizeKey(match[1]);
|
||||
const injectPayload = normalizedMap[mapKey];
|
||||
// 清洗提取到的特征词,并去 O(1) 字典中取值
|
||||
const normalizedMatchedKeyword = normalizeFeatureKeyword(featureMatch[1]);
|
||||
const injectedFeatureLabel = normalizedFeatureMap[normalizedMatchedKeyword];
|
||||
|
||||
if (!injectPayload) return p; // 兜底安全校验
|
||||
if (!injectedFeatureLabel) return proxy; // 兜底安全校验
|
||||
|
||||
// C. 格式化组装与幂等校验 (防重复注入 Bug)
|
||||
const formatStr = ` [${injectPayload}]`;
|
||||
if (name.includes(formatStr)) {
|
||||
return p;
|
||||
// 格式化组装与幂等校验 (防重复注入 Bug)
|
||||
const formattedFeatureLabel = ` [${injectedFeatureLabel}]`;
|
||||
if (proxyName.includes(formattedFeatureLabel)) {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
// D. 实施中缀注入 (Infix Injection)
|
||||
if (suffixRegex.test(name)) {
|
||||
p.name = name.replace(suffixRegex, `${formatStr}$1`);
|
||||
// 实施中缀注入 (Infix Injection)
|
||||
if (suffixRegex.test(proxyName)) {
|
||||
proxy.name = proxyName.replace(suffixRegex, `${formattedFeatureLabel}$1`);
|
||||
} else {
|
||||
// 纯净节点无后缀时,直接挂载在末尾
|
||||
p.name = name + formatStr;
|
||||
proxy.name = proxyName + formattedFeatureLabel;
|
||||
}
|
||||
|
||||
return p;
|
||||
return proxy;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user