DevTools Regex: schwarze Seite behoben, Zahlenbereich enthält-nicht, Test mit Exakt-Toggle

This commit is contained in:
2026-06-01 13:38:17 +02:00
parent a6dd7ab09c
commit 2b6f8da0f9

View File

@@ -1425,6 +1425,7 @@ const RULE_TYPES = [
{ id:'minlength', label:'Mindestlänge', fields:['count'], hint:'5' },
{ id:'maxlength', label:'Höchstlänge', fields:['count'], hint:'20' },
{ id:'numrange', label:'Zahlenbereich (enthält)', fields:['min','max'], hint:'' },
{ id:'numrange_not', label:'Zahlenbereich (enthält nicht)',fields:['min','max'], hint:'' },
{ id:'numrange_exact',label:'Zahlenbereich (exakt)', fields:['min','max'], hint:'' },
{ id:'onlynums', label:'Nur Zahlen', fields:[], hint:'' },
{ id:'onlyletters', label:'Nur Buchstaben', fields:[], hint:'' },
@@ -1462,6 +1463,7 @@ function ruleToRegex(rule) {
case 'minlength': return { pat: `.{${f.count||1},}`, desc: `mindestens ${f.count||1} Zeichen lang` };
case 'maxlength': return { pat: `.{0,${f.count||999}}`, desc: `höchstens ${f.count||999} Zeichen lang` };
case 'numrange': return { pat: `(?:${buildNumRange(Number(f.min||0), Number(f.max||9))})`, desc: `enthält eine Zahl zwischen ${f.min||0} und ${f.max||9}` };
case 'numrange_not': return { pat: `^(?!.*(?:${buildNumRange(Number(f.min||0), Number(f.max||9))})).*$`, desc: `enthält KEINE Zahl zwischen ${f.min||0} und ${f.max||9}` };
case 'numrange_exact': return { pat: `^(?:${buildNumRange(Number(f.min||0), Number(f.max||9))})$`, desc: `ist exakt eine Zahl zwischen ${f.min||0} und ${f.max||9}` };
case 'onlynums': return { pat: `^\\d+$`, desc: `nur Ziffern (09)` };
case 'onlyletters': return { pat: `^[a-zA-ZäöüÄÖÜß]+$`, desc: `nur Buchstaben` };
@@ -1697,6 +1699,7 @@ function RegexBuilder({ toast, mobile }) {
// ── Build mode ──
const [rules, setRules] = useState([]);
const [testVal, setTestVal] = useState('');
const [testExact, setTestExact] = useState(true);
const [copied, setCopied] = useState(false);
function addRule() {
@@ -1728,7 +1731,8 @@ function RegexBuilder({ toast, mobile }) {
let testResult = null;
if (regex && testVal !== '') {
try {
testResult = new RegExp(regex).test(testVal);
const pat = testExact ? `^(?:${regex})$` : regex;
testResult = new RegExp(pat).test(testVal);
} catch(e) { testResult = null; }
}
@@ -1741,13 +1745,18 @@ function RegexBuilder({ toast, mobile }) {
// ── Explain mode ──
const [explainInput, setExplainInput] = useState('');
const [explainTestVal, setExplainTestVal] = useState('');
const [explainExact, setExplainExact] = useState(false);
const explained = explainInput ? explainRegex(explainInput) : [];
let explainTestResult = null;
if (explainInput && explainTestVal !== '') {
try { explainTestResult = new RegExp(explainInput).test(explainTestVal); } catch {}
try {
const pat = explainExact ? `^(?:${explainInput})$` : explainInput;
explainTestResult = new RegExp(pat).test(explainTestVal);
} catch {}
}
const inp = {...S.inp, fontSize:13, padding:'7px 9px', boxSizing:'border-box'};
const lbl = {color:'rgba(255,255,255,0.55)', fontFamily:'monospace', fontSize:10, marginBottom:3};
return (
<div>
{/* Mode tabs */}
@@ -1801,7 +1810,15 @@ function RegexBuilder({ toast, mobile }) {
{/* Test-Bereich */}
<div style={{borderRadius:9,background:'rgba(255,255,255,0.03)',
border:'1px solid rgba(255,255,255,0.08)',padding:'12px 14px'}}>
<div style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:10,marginBottom:8}}>TESTEN</div>
<div style={{display:'flex',alignItems:'center',gap:12,marginBottom:8,flexWrap:'wrap'}}>
<span style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:10}}>TESTEN</span>
<label style={{display:'flex',alignItems:'center',gap:6,cursor:'pointer'}}>
<input type="checkbox" checked={testExact} onChange={e=>setTestExact(e.target.checked)}/>
<span style={{color:'rgba(255,255,255,0.5)',fontFamily:'monospace',fontSize:10}}>
Exakt (^$) ganzer Text muss passen
</span>
</label>
</div>
<div style={{display:'flex',gap:10,alignItems:'center',flexWrap:'wrap'}}>
<input style={{...inp,flex:1,minWidth:160}} placeholder="Testwert eingeben…"
value={testVal} onChange={e=>setTestVal(e.target.value)}/>
@@ -1848,7 +1865,15 @@ function RegexBuilder({ toast, mobile }) {
{/* Test */}
<div style={{borderRadius:9,background:'rgba(255,255,255,0.03)',
border:'1px solid rgba(255,255,255,0.08)',padding:'12px 14px'}}>
<div style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:10,marginBottom:8}}>TESTEN</div>
<div style={{display:'flex',alignItems:'center',gap:12,marginBottom:8,flexWrap:'wrap'}}>
<span style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:10}}>TESTEN</span>
<label style={{display:'flex',alignItems:'center',gap:6,cursor:'pointer'}}>
<input type="checkbox" checked={explainExact} onChange={e=>setExplainExact(e.target.checked)}/>
<span style={{color:'rgba(255,255,255,0.5)',fontFamily:'monospace',fontSize:10}}>
Exakt (^…$)
</span>
</label>
</div>
<div style={{display:'flex',gap:10,alignItems:'center',flexWrap:'wrap'}}>
<input style={{...inp,flex:1,minWidth:160}} placeholder="Testwert eingeben"
value={explainTestVal} onChange={e=>setExplainTestVal(e.target.value)}/>