Skip to content

Commit d2d5b44

Browse files
committed
added builder section
1 parent a8936d8 commit d2d5b44

File tree

3 files changed

+487
-41
lines changed

3 files changed

+487
-41
lines changed

index.html

Lines changed: 109 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,33 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<title>RegexLab - Interactive Regex Testing Tool</title>
77
<link rel="stylesheet" href="styles.css">
8+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
89
</head>
910
<body>
1011
<div class="container">
11-
<h1>RegexLab</h1>
12+
<header>
13+
<h1>
14+
<i class="fas fa-code"></i> RegexLab <small>Regex Testing Companion</small>
15+
</h1>
16+
</header>
1217
<div class="card">
1318
<div class="tabs">
1419
<div class="tab-headers">
15-
<button class="tab-header active" data-tab="test">Test Regex</button>
16-
<button class="tab-header" data-tab="builder">Regex Builder</button>
20+
<button class="tab-header active" data-tab="test">
21+
<i class="fas fa-search"></i> Test Regex </button>
22+
<button class="tab-header" data-tab="builder">
23+
<i class="fas fa-puzzle-piece"></i> Regex Builder </button>
24+
<button class="tab-header" data-tab="reference">
25+
<i class="fas fa-book"></i> Quick Reference </button>
1726
</div>
1827
<div class="tab-content active" id="test-tab">
1928
<div class="input-group">
20-
<label>Regular Expression</label>
29+
<label>
30+
<i class="fas fa-code"></i> Regular Expression </label>
2131
<div class="input-wrapper">
22-
<input type="text" id="regex-pattern" placeholder="Enter regex pattern">
23-
<select id="regex-presets">
24-
<option value="">Presets</option>
32+
<input type="text" id="regex-pattern" placeholder="Enter regex pattern" required>
33+
<select id="regex-presets" aria-label="Regex Presets">
34+
<option value="">Quick Presets</option>
2535
<option value="email">Email</option>
2636
<option value="phone">Phone Number</option>
2737
<option value="url">URL</option>
@@ -30,25 +40,110 @@ <h1>RegexLab</h1>
3040
</div>
3141
</div>
3242
<div class="input-group">
33-
<label>Regex Flags</label>
43+
<label>
44+
<i class="fas fa-flag"></i> Regex Flags </label>
3445
<input type="text" id="regex-flags" placeholder="Optional flags (g, i, m)">
3546
</div>
3647
<div class="input-group">
37-
<label>Test String</label>
38-
<input type="text" id="test-string" placeholder="Enter text to match against">
48+
<label>
49+
<i class="fas fa-paragraph"></i> Test String </label>
50+
<input type="text" id="test-string" placeholder="Enter text to match against" required>
3951
</div>
40-
<button id="test-regex-btn" class="primary-btn">Test Regex</button>
41-
<div id="validation-error" class="error-message"></div>
52+
<button id="test-regex-btn" class="primary-btn">
53+
<i class="fas fa-play"></i> Run Test </button>
54+
<div id="validation-error" class="error-message" aria-live="polite"></div>
4255
<div id="matches-container" class="matches-section">
43-
<h3>Matches:</h3>
56+
<h3>
57+
<i class="fas fa-list"></i> Matches:
58+
</h3>
4459
<div id="matches-list"></div>
4560
</div>
4661
</div>
4762
<div class="tab-content" id="builder-tab">
48-
<div class="coming-soon"> Regex Builder Coming Soon! </div>
63+
<div class="regex-builder">
64+
<div class="input-group">
65+
<label>
66+
<i class="fas fa-code"></i> Generated Regex </label>
67+
<input type="text" id="generated-regex" placeholder="Your regex will appear here" readonly>
68+
</div>
69+
<div class="regex-builder-actions">
70+
<button id="copy-regex-btn" class="primary-btn">
71+
<i class="fas fa-copy"></i> Copy Regex </button>
72+
<button id="clear-regex-btn" class="primary-btn">
73+
<i class="fas fa-trash"></i> Clear </button>
74+
<button id="show-repeat-modal" class="primary-btn">
75+
<i class="fas fa-redo"></i> Repeat </button>
76+
</div>
77+
<div class="builder-category">
78+
<h4>
79+
<i class="fas fa-font"></i> Character Classes
80+
</h4>
81+
<div id="character-classes" class="builder-options-grid"></div>
82+
</div>
83+
<div class="custom-char-class">
84+
<input type="text" id="custom-char-class" placeholder="Enter custom character class (e.g., a-zA-Z)">
85+
<button id="custom-char-class-btn" class="primary-btn">Add</button>
86+
</div>
87+
<div class="builder-category">
88+
<h4>
89+
<i class="fas fa-ruler"></i> Quantifiers
90+
</h4>
91+
<div id="quantifiers" class="builder-options-grid"></div>
92+
</div>
93+
<div class="builder-category">
94+
<h4>
95+
<i class="fas fa-anchor"></i> Anchors & Groups
96+
</h4>
97+
<div id="anchors-groups" class="builder-options-grid"></div>
98+
</div>
99+
</div>
100+
</div>
101+
<div id="repeat-modal" class="repeat-modal">
102+
<div class="repeat-modal-content">
103+
<h3>Specify Repeat</h3>
104+
<input type="text" id="repeat-input" placeholder="Example: 3 or 2,4">
105+
<button id="repeat-confirm" class="primary-btn">Confirm</button>
106+
</div>
107+
</div>
108+
<div class="tab-content" id="reference-tab">
109+
<div class="reference-content">
110+
<h3>
111+
<i class="fas fa-book-open"></i> Regex Cheat Sheet
112+
</h3>
113+
<div class="reference-grid">
114+
<div class="reference-item">
115+
<strong>^</strong> Start of string
116+
</div>
117+
<div class="reference-item">
118+
<strong>$</strong> End of string
119+
</div>
120+
<div class="reference-item">
121+
<strong>.</strong> Any character
122+
</div>
123+
<div class="reference-item">
124+
<strong>*</strong> 0 or more
125+
</div>
126+
<div class="reference-item">
127+
<strong>+</strong> 1 or more
128+
</div>
129+
<div class="reference-item">
130+
<strong>?</strong> 0 or 1
131+
</div>
132+
</div>
133+
</div>
49134
</div>
50135
</div>
51136
</div>
137+
<footer>
138+
<p> Created with <i class="fas fa-heart"></i> by ThatSINEWAVE </p>
139+
</footer>
140+
</div>
141+
<div id="repeat-modal" class="repeat-modal">
142+
<div class="repeat-modal-content">
143+
<h3>Specify Repeat</h3>
144+
<input type="text" id="repeat-input" placeholder="Example: 3 or 2,4">
145+
<button id="repeat-confirm" class="primary-btn">Confirm</button>
146+
</div>
52147
</div>
53148
<script src="script.js"></script>
54149
</body>

script.js

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ document.addEventListener('DOMContentLoaded', () => {
2222
});
2323
});
2424

25-
// Regex testing logic
25+
// Regex Testing Logic
2626
const regexPatternInput = document.getElementById('regex-pattern');
2727
const regexFlagsInput = document.getElementById('regex-flags');
2828
const testStringInput = document.getElementById('test-string');
@@ -80,4 +80,130 @@ document.addEventListener('DOMContentLoaded', () => {
8080
validationErrorEl.textContent = error.message;
8181
}
8282
});
83+
84+
// Regex Builder Logic
85+
const builderElements = {
86+
characterClasses: document.getElementById('character-classes'),
87+
quantifiers: document.getElementById('quantifiers'),
88+
anchorsGroups: document.getElementById('anchors-groups'),
89+
generatedRegex: document.getElementById('generated-regex'),
90+
copyRegexBtn: document.getElementById('copy-regex-btn')
91+
};
92+
93+
const regexBuilderOptions = {
94+
characterClasses: {
95+
'Digit': '\\d',
96+
'Non-Digit': '\\D',
97+
'Word Character': '\\w',
98+
'Non-Word Character': '\\W',
99+
'Whitespace': '\\s',
100+
'Non-Whitespace': '\\S'
101+
},
102+
quantifiers: {
103+
'Zero or More': '*',
104+
'One or More': '+',
105+
'Zero or One': '?',
106+
'Exactly': '{n}',
107+
'At Least': '{n,}',
108+
'Between': '{n,m}'
109+
},
110+
anchorsGroups: {
111+
'Start of Line': '^',
112+
'End of Line': '$',
113+
'Word Boundary': '\\b',
114+
'Non-Word Boundary': '\\B'
115+
}
116+
};
117+
118+
function populateBuilderOptions() {
119+
const categoryContainers = {
120+
'character-classes': builderElements.characterClasses,
121+
'quantifiers': builderElements.quantifiers,
122+
'anchors-groups': builderElements.anchorsGroups
123+
};
124+
125+
Object.entries(regexBuilderOptions).forEach(([category, options]) => {
126+
const containerKey = category.replace(/([A-Z])/g, '-$1').toLowerCase();
127+
const container = categoryContainers[containerKey];
128+
129+
if (container) {
130+
container.innerHTML = '';
131+
Object.entries(options).forEach(([label, value]) => {
132+
const button = document.createElement('button');
133+
button.classList.add('builder-option');
134+
button.textContent = label;
135+
button.dataset.value = value;
136+
button.addEventListener('click', () => appendToRegex(value));
137+
container.appendChild(button);
138+
});
139+
}
140+
});
141+
}
142+
143+
function appendToRegex(value) {
144+
const currentRegex = builderElements.generatedRegex.value;
145+
builderElements.generatedRegex.value = currentRegex + value;
146+
}
147+
148+
function initRegexBuilder() {
149+
populateBuilderOptions();
150+
151+
// Custom character class builder
152+
const customCharClassBtn = document.getElementById('custom-char-class-btn');
153+
const customCharClassInput = document.getElementById('custom-char-class');
154+
155+
customCharClassBtn.addEventListener('click', () => {
156+
const customClass = customCharClassInput.value.trim();
157+
if (customClass) {
158+
appendToRegex(`[${customClass}]`);
159+
customCharClassInput.value = '';
160+
}
161+
});
162+
163+
// Repeater modal
164+
const repeatModal = document.getElementById('repeat-modal');
165+
const repeatInput = document.getElementById('repeat-input');
166+
const repeatConfirmBtn = document.getElementById('repeat-confirm');
167+
const showRepeatModalBtn = document.getElementById('show-repeat-modal');
168+
169+
showRepeatModalBtn.addEventListener('click', () => {
170+
repeatModal.style.display = 'block';
171+
});
172+
173+
repeatConfirmBtn.addEventListener('click', () => {
174+
const repeatValue = repeatInput.value.trim();
175+
if (repeatValue) {
176+
appendToRegex(`{${repeatValue}}`);
177+
repeatModal.style.display = 'none';
178+
repeatInput.value = '';
179+
}
180+
});
181+
182+
// Close modal when clicking outside
183+
window.addEventListener('click', (event) => {
184+
if (event.target === repeatModal) {
185+
repeatModal.style.display = 'none';
186+
}
187+
});
188+
189+
// Copy regex button
190+
builderElements.copyRegexBtn.addEventListener('click', () => {
191+
const regexToCopy = builderElements.generatedRegex.value;
192+
navigator.clipboard.writeText(regexToCopy).then(() => {
193+
builderElements.copyRegexBtn.textContent = 'Copied!';
194+
setTimeout(() => {
195+
builderElements.copyRegexBtn.textContent = 'Copy Regex';
196+
}, 2000);
197+
});
198+
});
199+
200+
// Clear regex button
201+
const clearRegexBtn = document.getElementById('clear-regex-btn');
202+
clearRegexBtn.addEventListener('click', () => {
203+
builderElements.generatedRegex.value = '';
204+
});
205+
}
206+
207+
// Initialize Regex Builder
208+
initRegexBuilder();
83209
});

0 commit comments

Comments
 (0)