css2class 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +1143 -0
- package/CHANGELOG.md +291 -0
- package/CONFIG.md +1096 -0
- package/CONTRIBUTING.md +571 -0
- package/MIGRATION.md +402 -0
- package/README.md +634 -0
- package/bin/class2css.js +380 -0
- package/class2css.config.js +124 -0
- package/common.css +3 -0
- package/configs/colors.config.js +62 -0
- package/configs/layout.config.js +110 -0
- package/configs/spacing.config.js +37 -0
- package/configs/typography.config.js +41 -0
- package/docs/.vitepress/config.mjs +65 -0
- package/docs/.vitepress/theme/custom.css +74 -0
- package/docs/.vitepress/theme/index.js +7 -0
- package/docs/guide/cli.md +97 -0
- package/docs/guide/concepts.md +63 -0
- package/docs/guide/config-template.md +365 -0
- package/docs/guide/config.md +275 -0
- package/docs/guide/faq.md +202 -0
- package/docs/guide/getting-started.md +83 -0
- package/docs/guide/important-and-static.md +67 -0
- package/docs/guide/incremental.md +162 -0
- package/docs/guide/rules-reference.md +354 -0
- package/docs/guide/units.md +57 -0
- package/docs/index.md +68 -0
- package/package.json +49 -0
- package/run.js +90 -0
- package/src/README.md +571 -0
- package/src/core/CacheManager.js +650 -0
- package/src/core/CompatibilityAdapter.js +264 -0
- package/src/core/ConfigManager.js +431 -0
- package/src/core/ConfigValidator.js +350 -0
- package/src/core/EventBus.js +77 -0
- package/src/core/FullScanManager.js +430 -0
- package/src/core/StateManager.js +631 -0
- package/src/docs/DocsServer.js +179 -0
- package/src/example.js +106 -0
- package/src/generators/DynamicClassGenerator.js +674 -0
- package/src/index.js +1046 -0
- package/src/parsers/ClassParser.js +572 -0
- package/src/parsers/ImportantParser.js +279 -0
- package/src/parsers/RegexCompiler.js +200 -0
- package/src/utils/ClassChangeTracker.js +366 -0
- package/src/utils/ConfigDiagnostics.js +673 -0
- package/src/utils/CssFormatter.js +261 -0
- package/src/utils/FileUtils.js +230 -0
- package/src/utils/Logger.js +150 -0
- package/src/utils/Throttle.js +172 -0
- package/src/utils/UnitProcessor.js +334 -0
- package/src/utils/WxssClassExtractor.js +137 -0
- package/src/watchers/ConfigWatcher.js +413 -0
- package/src/watchers/FileWatcher.js +133 -0
- package/src/writers/FileWriter.js +302 -0
- package/src/writers/UnifiedWriter.js +370 -0
- package/styles.config.js +250 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
class ImportantParser {
|
|
2
|
+
constructor(eventBus, importantFlags) {
|
|
3
|
+
this.eventBus = eventBus;
|
|
4
|
+
this.importantFlags = importantFlags;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// 检测类名是否包含Important标识
|
|
8
|
+
hasImportantFlag(className) {
|
|
9
|
+
if (!className || typeof className !== 'string') {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// 检查前缀标识
|
|
14
|
+
for (const prefix of this.importantFlags.prefix) {
|
|
15
|
+
if (className.startsWith(prefix)) {
|
|
16
|
+
this.eventBus.emit('important:detected', { className, type: 'prefix', flag: prefix });
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// 检查后缀标识
|
|
22
|
+
for (const suffix of this.importantFlags.suffix) {
|
|
23
|
+
if (className.endsWith(suffix)) {
|
|
24
|
+
this.eventBus.emit('important:detected', { className, type: 'suffix', flag: suffix });
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 检查自定义标识
|
|
30
|
+
for (const custom of this.importantFlags.custom) {
|
|
31
|
+
if (className.includes(custom)) {
|
|
32
|
+
this.eventBus.emit('important:detected', { className, type: 'custom', flag: custom });
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 清理Important标识,返回干净的类名
|
|
41
|
+
cleanImportantFlag(className) {
|
|
42
|
+
if (!className || typeof className !== 'string') {
|
|
43
|
+
return className;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let cleanName = className;
|
|
47
|
+
let removedFlag = null;
|
|
48
|
+
let removedType = null;
|
|
49
|
+
|
|
50
|
+
// 清理前缀标识
|
|
51
|
+
for (const prefix of this.importantFlags.prefix) {
|
|
52
|
+
if (cleanName.startsWith(prefix)) {
|
|
53
|
+
cleanName = cleanName.substring(prefix.length);
|
|
54
|
+
removedFlag = prefix;
|
|
55
|
+
removedType = 'prefix';
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 清理后缀标识
|
|
61
|
+
if (!removedFlag) {
|
|
62
|
+
for (const suffix of this.importantFlags.suffix) {
|
|
63
|
+
if (cleanName.endsWith(suffix)) {
|
|
64
|
+
cleanName = cleanName.substring(0, cleanName.length - suffix.length);
|
|
65
|
+
removedFlag = suffix;
|
|
66
|
+
removedType = 'suffix';
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 清理自定义标识
|
|
73
|
+
if (!removedFlag) {
|
|
74
|
+
for (const custom of this.importantFlags.custom) {
|
|
75
|
+
if (cleanName.includes(custom)) {
|
|
76
|
+
cleanName = cleanName.replace(custom, '');
|
|
77
|
+
removedFlag = custom;
|
|
78
|
+
removedType = 'custom';
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (removedFlag) {
|
|
85
|
+
this.eventBus.emit('important:cleaned', {
|
|
86
|
+
original: className,
|
|
87
|
+
cleaned: cleanName,
|
|
88
|
+
removedFlag,
|
|
89
|
+
removedType,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return cleanName;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 为CSS值添加!important
|
|
97
|
+
addImportantToCss(cssValue, isImportant) {
|
|
98
|
+
if (!isImportant) {
|
|
99
|
+
return cssValue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 如果已经包含!important,直接返回
|
|
103
|
+
if (cssValue.includes('!important')) {
|
|
104
|
+
return cssValue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 清理末尾的分号和空格
|
|
108
|
+
const cleanValue = cssValue.replace(/;?\s*$/, '');
|
|
109
|
+
const result = `${cleanValue} !important;`;
|
|
110
|
+
|
|
111
|
+
this.eventBus.emit('important:added', { original: cssValue, result });
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 批量处理Important标识
|
|
116
|
+
batchProcessImportant(classNames) {
|
|
117
|
+
const results = [];
|
|
118
|
+
|
|
119
|
+
for (const className of classNames) {
|
|
120
|
+
const isImportant = this.hasImportantFlag(className);
|
|
121
|
+
const cleanName = this.cleanImportantFlag(className);
|
|
122
|
+
|
|
123
|
+
results.push({
|
|
124
|
+
original: className,
|
|
125
|
+
clean: cleanName,
|
|
126
|
+
isImportant,
|
|
127
|
+
hasImportantFlag: isImportant,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
this.eventBus.emit('important:batch:processed', {
|
|
132
|
+
totalCount: classNames.length,
|
|
133
|
+
importantCount: results.filter((r) => r.isImportant).length,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return results;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// 验证Important标识配置
|
|
140
|
+
validateImportantFlags() {
|
|
141
|
+
const errors = [];
|
|
142
|
+
const warnings = [];
|
|
143
|
+
|
|
144
|
+
// 检查前缀标识
|
|
145
|
+
if (!Array.isArray(this.importantFlags.prefix)) {
|
|
146
|
+
errors.push('importantFlags.prefix must be an array');
|
|
147
|
+
} else {
|
|
148
|
+
this.importantFlags.prefix.forEach((flag, index) => {
|
|
149
|
+
if (typeof flag !== 'string' || flag.length === 0) {
|
|
150
|
+
errors.push(`importantFlags.prefix[${index}] must be a non-empty string`);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 检查后缀标识
|
|
156
|
+
if (!Array.isArray(this.importantFlags.suffix)) {
|
|
157
|
+
errors.push('importantFlags.suffix must be an array');
|
|
158
|
+
} else {
|
|
159
|
+
this.importantFlags.suffix.forEach((flag, index) => {
|
|
160
|
+
if (typeof flag !== 'string' || flag.length === 0) {
|
|
161
|
+
errors.push(`importantFlags.suffix[${index}] must be a non-empty string`);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// 检查自定义标识
|
|
167
|
+
if (!Array.isArray(this.importantFlags.custom)) {
|
|
168
|
+
errors.push('importantFlags.custom must be an array');
|
|
169
|
+
} else {
|
|
170
|
+
this.importantFlags.custom.forEach((flag, index) => {
|
|
171
|
+
if (typeof flag !== 'string' || flag.length === 0) {
|
|
172
|
+
errors.push(`importantFlags.custom[${index}] must be a non-empty string`);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 检查标识冲突
|
|
178
|
+
const allFlags = [
|
|
179
|
+
...this.importantFlags.prefix,
|
|
180
|
+
...this.importantFlags.suffix,
|
|
181
|
+
...this.importantFlags.custom,
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
const duplicates = allFlags.filter((flag, index) => allFlags.indexOf(flag) !== index);
|
|
185
|
+
if (duplicates.length > 0) {
|
|
186
|
+
warnings.push(`Duplicate important flags detected: ${duplicates.join(', ')}`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return { errors, warnings, isValid: errors.length === 0 };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// 获取Important标识统计
|
|
193
|
+
getImportantStats() {
|
|
194
|
+
return {
|
|
195
|
+
prefixCount: this.importantFlags.prefix.length,
|
|
196
|
+
suffixCount: this.importantFlags.suffix.length,
|
|
197
|
+
customCount: this.importantFlags.custom.length,
|
|
198
|
+
totalFlags:
|
|
199
|
+
this.importantFlags.prefix.length +
|
|
200
|
+
this.importantFlags.suffix.length +
|
|
201
|
+
this.importantFlags.custom.length,
|
|
202
|
+
flags: {
|
|
203
|
+
prefix: [...this.importantFlags.prefix],
|
|
204
|
+
suffix: [...this.importantFlags.suffix],
|
|
205
|
+
custom: [...this.importantFlags.custom],
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// 更新Important标识配置
|
|
211
|
+
updateImportantFlags(newImportantFlags) {
|
|
212
|
+
const oldFlags = { ...this.importantFlags };
|
|
213
|
+
this.importantFlags = newImportantFlags;
|
|
214
|
+
|
|
215
|
+
this.eventBus.emit('important:flags:updated', {
|
|
216
|
+
old: oldFlags,
|
|
217
|
+
new: newImportantFlags,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// 测试Important标识
|
|
222
|
+
testImportantFlags(testClassNames) {
|
|
223
|
+
const results = [];
|
|
224
|
+
|
|
225
|
+
for (const className of testClassNames) {
|
|
226
|
+
const isImportant = this.hasImportantFlag(className);
|
|
227
|
+
const cleanName = this.cleanImportantFlag(className);
|
|
228
|
+
|
|
229
|
+
results.push({
|
|
230
|
+
className,
|
|
231
|
+
isImportant,
|
|
232
|
+
cleanName,
|
|
233
|
+
originalLength: className.length,
|
|
234
|
+
cleanLength: cleanName.length,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return results;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// 生成Important标识示例
|
|
242
|
+
generateExamples() {
|
|
243
|
+
const examples = [];
|
|
244
|
+
|
|
245
|
+
// 前缀示例
|
|
246
|
+
this.importantFlags.prefix.forEach((prefix) => {
|
|
247
|
+
examples.push({
|
|
248
|
+
type: 'prefix',
|
|
249
|
+
flag: prefix,
|
|
250
|
+
example: `${prefix}w-100`,
|
|
251
|
+
description: `Class with prefix flag "${prefix}"`,
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// 后缀示例
|
|
256
|
+
this.importantFlags.suffix.forEach((suffix) => {
|
|
257
|
+
examples.push({
|
|
258
|
+
type: 'suffix',
|
|
259
|
+
flag: suffix,
|
|
260
|
+
example: `w-100${suffix}`,
|
|
261
|
+
description: `Class with suffix flag "${suffix}"`,
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// 自定义示例
|
|
266
|
+
this.importantFlags.custom.forEach((custom) => {
|
|
267
|
+
examples.push({
|
|
268
|
+
type: 'custom',
|
|
269
|
+
flag: custom,
|
|
270
|
+
example: `w-100${custom}`,
|
|
271
|
+
description: `Class with custom flag "${custom}"`,
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
return examples;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
module.exports = ImportantParser;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
class RegexCompiler {
|
|
2
|
+
constructor(eventBus, importantFlags) {
|
|
3
|
+
this.eventBus = eventBus;
|
|
4
|
+
this.importantFlags = importantFlags;
|
|
5
|
+
this.compiledRegex = null;
|
|
6
|
+
this.cache = new Map();
|
|
7
|
+
|
|
8
|
+
this.compileRegex();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
escapeRegex(string) {
|
|
12
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
compileRegex() {
|
|
16
|
+
try {
|
|
17
|
+
const allFlags = [
|
|
18
|
+
...this.importantFlags.prefix.map((flag) => `^${this.escapeRegex(flag)}`),
|
|
19
|
+
...this.importantFlags.suffix.map((flag) => `${this.escapeRegex(flag)}$`),
|
|
20
|
+
...this.importantFlags.custom.map((flag) => this.escapeRegex(flag)),
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
this.compiledRegex = {
|
|
24
|
+
classAttr: /class=(\"[^\"]*\"|'[^']*')/g,
|
|
25
|
+
classNames: /[\w\-!]+/g,
|
|
26
|
+
importantFlag: new RegExp(allFlags.join('|')),
|
|
27
|
+
twoPartClass: /^([a-zA-Z_]+)-(.+)$/,
|
|
28
|
+
percentageValue: /(\d+)b$/,
|
|
29
|
+
whitespace: /\s+/g,
|
|
30
|
+
quotes: /^["']|["']$/g,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
this.eventBus.emit('regex:compiled', this.compiledRegex);
|
|
34
|
+
this.eventBus.emit('parser:regex:ready');
|
|
35
|
+
} catch (error) {
|
|
36
|
+
this.eventBus.emit('regex:compilation:error', error);
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 获取编译后的正则表达式
|
|
42
|
+
getCompiledRegex() {
|
|
43
|
+
return this.compiledRegex;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 更新Important标识并重新编译
|
|
47
|
+
updateImportantFlags(importantFlags) {
|
|
48
|
+
this.importantFlags = importantFlags;
|
|
49
|
+
this.compileRegex();
|
|
50
|
+
this.clearCache();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 缓存管理
|
|
54
|
+
getCachedRegex(key) {
|
|
55
|
+
return this.cache.get(key);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setCachedRegex(key, regex) {
|
|
59
|
+
this.cache.set(key, regex);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
clearCache() {
|
|
63
|
+
this.cache.clear();
|
|
64
|
+
this.eventBus.emit('regex:cache:cleared');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 正则表达式测试工具
|
|
68
|
+
testClassAttribute(text) {
|
|
69
|
+
if (!this.compiledRegex.classAttr) return false;
|
|
70
|
+
|
|
71
|
+
const testRegex = new RegExp(
|
|
72
|
+
this.compiledRegex.classAttr.source,
|
|
73
|
+
this.compiledRegex.classAttr.flags
|
|
74
|
+
);
|
|
75
|
+
return testRegex.test(text);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
testImportantFlag(className) {
|
|
79
|
+
if (!this.compiledRegex.importantFlag) return false;
|
|
80
|
+
|
|
81
|
+
return this.compiledRegex.importantFlag.test(className);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
testTwoPartClass(className) {
|
|
85
|
+
if (!this.compiledRegex.twoPartClass) return false;
|
|
86
|
+
|
|
87
|
+
return this.compiledRegex.twoPartClass.test(className);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 正则表达式匹配工具
|
|
91
|
+
matchClassAttributes(htmlStr) {
|
|
92
|
+
if (!this.compiledRegex.classAttr) return [];
|
|
93
|
+
|
|
94
|
+
const matches = [];
|
|
95
|
+
let match;
|
|
96
|
+
const regex = new RegExp(
|
|
97
|
+
this.compiledRegex.classAttr.source,
|
|
98
|
+
this.compiledRegex.classAttr.flags
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
while ((match = regex.exec(htmlStr)) !== null) {
|
|
102
|
+
matches.push({
|
|
103
|
+
fullMatch: match[0],
|
|
104
|
+
classContent: match[1],
|
|
105
|
+
index: match.index,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return matches;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
matchClassNames(classStr) {
|
|
113
|
+
if (!this.compiledRegex.classNames) return [];
|
|
114
|
+
|
|
115
|
+
const matches = [];
|
|
116
|
+
let match;
|
|
117
|
+
const regex = new RegExp(
|
|
118
|
+
this.compiledRegex.classNames.source,
|
|
119
|
+
this.compiledRegex.classNames.flags
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
while ((match = regex.exec(classStr)) !== null) {
|
|
123
|
+
matches.push({
|
|
124
|
+
className: match[0],
|
|
125
|
+
index: match.index,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return matches;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 性能优化:预编译常用正则
|
|
133
|
+
precompileCommonPatterns() {
|
|
134
|
+
const commonPatterns = {
|
|
135
|
+
// 常见的CSS类名模式
|
|
136
|
+
cssClass: /^[a-zA-Z_][\w\-]*$/,
|
|
137
|
+
// 数值模式
|
|
138
|
+
number: /^\d+(\.\d+)?$/,
|
|
139
|
+
// 单位模式
|
|
140
|
+
unit: /^(px|em|rem|%|vw|vh|pt|cm|mm|in)$/,
|
|
141
|
+
// 颜色模式
|
|
142
|
+
color:
|
|
143
|
+
/^(#[0-9a-fA-F]{3,6}|rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)|rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\))$/,
|
|
144
|
+
// 媒体查询
|
|
145
|
+
mediaQuery: /^@media\s+[^{]+$/,
|
|
146
|
+
// 选择器
|
|
147
|
+
selector: /^[.#]?[\w\-]+(\.[\w\-]+)*(\[[^\]]+\])?(:[^\s]+)*$/,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
Object.entries(commonPatterns).forEach(([key, pattern]) => {
|
|
151
|
+
this.setCachedRegex(key, pattern);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
this.eventBus.emit('regex:common:precompiled', Object.keys(commonPatterns));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// 正则表达式验证
|
|
158
|
+
validateRegex(pattern, flags = '') {
|
|
159
|
+
try {
|
|
160
|
+
new RegExp(pattern, flags);
|
|
161
|
+
return { valid: true };
|
|
162
|
+
} catch (error) {
|
|
163
|
+
return { valid: false, error: error.message };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 正则表达式统计
|
|
168
|
+
getRegexStats() {
|
|
169
|
+
return {
|
|
170
|
+
compiledCount: Object.keys(this.compiledRegex || {}).length,
|
|
171
|
+
cacheSize: this.cache.size,
|
|
172
|
+
importantFlagsCount: {
|
|
173
|
+
prefix: this.importantFlags.prefix.length,
|
|
174
|
+
suffix: this.importantFlags.suffix.length,
|
|
175
|
+
custom: this.importantFlags.custom.length,
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// 调试工具
|
|
181
|
+
debugRegex(pattern, testString) {
|
|
182
|
+
const validation = this.validateRegex(pattern);
|
|
183
|
+
if (!validation.valid) {
|
|
184
|
+
return { error: validation.error };
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const regex = new RegExp(pattern);
|
|
188
|
+
const matches = testString.match(regex);
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
pattern,
|
|
192
|
+
testString,
|
|
193
|
+
matches,
|
|
194
|
+
matchCount: matches ? matches.length : 0,
|
|
195
|
+
isValid: validation.valid,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
module.exports = RegexCompiler;
|