irongit

A better version of regex 101

moonregex/src/builder.js
63 lines1.8 KBJavaScript
1export const readVars = (str) => {
2 let lines = str.split("\n");
3 const vars = {};
4 for (let i = 0; i < lines.length; i++) {
5 let line = lines[i];
6 let lineSplit = line.split(":==");
7 if ((lineSplit.length = 2)) {
8 let [name, val] = lineSplit;
9 vars[name] = val;
10 }
11 }
12 return vars;
13};
14
15const parseBuilder = (str, vars) => {
16 let lines = str.split("\n");
17 const ref = {};
18 for (let line of lines) {
19 if (!line.trim()) continue;
20 const r =
21 /^(?<tabs>\s*)(?<name>\w*)(?<optional>[\*\+\?]*)(?<type>[:>])(?<regex>.*)/.exec(
22 line
23 );
24 if (!r) return "";
25 const lineData = r.groups;
26 const tabs = lineData.tabs.length;
27 if (!ref[tabs]) ref[tabs] = [lineData];
28 else ref[tabs].push(lineData);
29 if (tabs) {
30 const parentRefInd = ref[tabs - 1].length - 1;
31 let parent = ref[tabs - 1][parentRefInd];
32 if (!parent.children) parent.children = [lineData];
33 else parent.children.push(lineData);
34 }
35 }
36 return buildToRegex(ref[0], vars);
37};
38
39const buildToRegex = (build, vars) => {
40 const re = buildToRegexRecursion(build, "", vars);
41 return re;
42};
43
44const buildToRegexRecursion = (build, re, vars) => {
45 if (!build?.length) return re;
46 const val = build.shift();
47 console.log(vars);
48 if (vars && Object.keys(vars).includes(val.regex))
49 val.regex = vars[val.regex];
50 if (val.type === ":") {
51 if (val.name) re += `(?P<${val.name}>${val.regex}`;
52 else re += `(?:${val.regex}`;
53 if (val.children) re += buildToRegexRecursion(val.children, "", vars);
54 re += `)${val.optional}`;
55 } else if (val.type === ">") {
56 re += val.regex;
57 if (val.children) re += buildToRegexRecursion(val.children, "", vars);
58 }
59
60 return buildToRegexRecursion(build, re, vars);
61};
62
63export default parseBuilder;