DevTools Regex: schwarze Seite behoben, Zahlenbereich enthält-nicht, Test mit Exakt-Toggle
This commit is contained in:
@@ -1424,8 +1424,9 @@ const RULE_TYPES = [
|
||||
{ id:'alnum_n', label:'Genau N Alphanumerisch',fields:['count'], hint:'8' },
|
||||
{ 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_exact',label:'Zahlenbereich (exakt)', fields:['min','max'], hint:'' },
|
||||
{ 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:'' },
|
||||
{ id:'onlyalnum', label:'Nur Alphanumerisch', fields:[], hint:'' },
|
||||
@@ -1461,8 +1462,9 @@ function ruleToRegex(rule) {
|
||||
case 'alnum_n': return { pat: `[a-zA-Z0-9]{${f.count||1}}`, desc: `genau ${f.count||1} alphanumerische Zeichen` };
|
||||
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_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 '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 (0–9)` };
|
||||
case 'onlyletters': return { pat: `^[a-zA-ZäöüÄÖÜß]+$`, desc: `nur Buchstaben` };
|
||||
case 'onlyalnum': return { pat: `^[a-zA-Z0-9]+$`, desc: `nur Buchstaben und Ziffern` };
|
||||
@@ -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,11 +1810,19 @@ 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)}/>
|
||||
{testResult===true && <span style={{color:'#4ecdc4',fontFamily:'monospace',fontSize:14,fontWeight:700}}>✓ Treffer</span>}
|
||||
{testResult===true && <span style={{color:'#4ecdc4',fontFamily:'monospace',fontSize:14,fontWeight:700}}>✓ Treffer</span>}
|
||||
{testResult===false && <span style={{color:'#ff6b9d',fontFamily:'monospace',fontSize:14,fontWeight:700}}>✗ Kein Treffer</span>}
|
||||
</div>
|
||||
</div>
|
||||
@@ -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)}/>
|
||||
|
||||
Reference in New Issue
Block a user