{"id":10289,"date":"2026-08-15T01:24:10","date_gmt":"2026-08-14T23:24:10","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/toolbox\/regex-tester-explainer\/"},"modified":"2026-08-15T01:24:10","modified_gmt":"2026-08-14T23:24:10","slug":"regex-tester-explainer","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/regex-tester-explainer\/","title":{"rendered":"Regex Tester &#038; Explainer"},"content":{"rendered":"<div class=\"gtm-analyser-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<p style=\"color: var(--text-secondary, #a0a0b0); margin-bottom: 20px;\">A regular expression that matches nothing looks exactly like one that matches everything. This tool shows the matches, takes the pattern apart piece by piece and points out the parts that behave differently from what they look like.<\/p>\n<div style=\"display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end;\">\n<div style=\"flex: 3; min-width: 240px;\">\n            <label for=\"rx-muster\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Pattern<\/label><br \/>\n            <input type=\"text\" id=\"rx-muster\" class=\"form-control\" style=\"width: 100%; padding: 12px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--accent, #7ee787); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" value=\"^utm_([a-z_]+)=([^&amp;\\s]+)$\">\n        <\/div>\n<div style=\"flex: 1; min-width: 150px;\">\n            <label for=\"rx-flaggen\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Flags<\/label><br \/>\n            <input type=\"text\" id=\"rx-flaggen\" class=\"form-control\" style=\"width: 100%; padding: 12px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" value=\"gm\">\n        <\/div>\n<\/p><\/div>\n<p>    <label for=\"rx-text\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin: 15px 0 5px;\">Text to test against<\/label><br \/>\n    <textarea id=\"rx-text\" class=\"form-control\" style=\"width: 100%; height: 120px; padding: 12px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; font-size: 0.85rem; box-sizing: border-box;\">utm_source=newsletter<br \/>\nutm_medium=email<br \/>\nutm_campaign=august_sale<br \/>\ngclid=EAIaIQobChMI<\/textarea><\/p>\n<div style=\"display: flex; gap: 10px; flex-wrap: wrap; margin: 18px 0 0;\">\n        <button id=\"rx-btn\" class=\"button\" style=\"background: var(--accent, #7ee787); color: #0b1114; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Test<\/button>\n    <\/div>\n<div id=\"rx-ergebnis\" style=\"margin-top: 22px;\"><\/div>\n<\/div>\n<p><script>\n(function () {\n    'use strict';<\/p>\n<p>    const T = {\"einleitung\":\"A regular expression that matches nothing looks exactly like one that matches everything. This tool shows the matches, takes the pattern apart piece by piece and points out the parts that behave differently from what they look like.\",\"label_muster\":\"Pattern\",\"label_flaggen\":\"Flags\",\"label_text\":\"Text to test against\",\"knopf\":\"Test\",\"fehler_leer\":\"No pattern was entered.\",\"fehler_flaggen\":\"Only the flags g, i, m, s, u and y exist.\",\"fehler_muster\":\"The pattern is not valid: %s\",\"h_treffer\":\"Matches (%s)\",\"h_erklaerung\":\"The pattern piece by piece\",\"h_befunde\":\"Findings\",\"keine_treffer\":\"The pattern matches nothing in this text.\",\"stelle\":\"at position %s\",\"gruppe\":\"group %n:\",\"abgeschnitten\":\"Only the first 20000 characters were tested.\",\"e_ziffer\":\"any digit\",\"e_keine_ziffer\":\"anything that is not a digit\",\"e_wort\":\"letter, digit or underscore\",\"e_kein_wort\":\"anything that is not a letter, digit or underscore\",\"e_leer\":\"any whitespace\",\"e_kein_leer\":\"anything that is not whitespace\",\"e_grenze\":\"a word boundary, which consumes no character\",\"e_keine_grenze\":\"a position that is not a word boundary\",\"e_zeilenumbruch\":\"a line break\",\"e_tabulator\":\"a tab\",\"e_wagenruecklauf\":\"a carriage return\",\"e_rueckverweis\":\"again exactly what group %s matched\",\"e_woertlich\":\"the character %s literally\",\"e_klasse\":\"one character out of: %s\",\"e_klasse_nicht\":\"any character except: %s\",\"e_gruppe\":\"start of group %s, which is captured\",\"e_gruppe_ohne\":\"start of a group that is not captured\",\"e_gruppe_name\":\"start of the group named %s\",\"e_gruppe_zu\":\"end of the group\",\"e_vorschau\":\"what follows has to come next, without being consumed\",\"e_vorschau_nicht\":\"what follows must not come next\",\"e_rueckschau\":\"what follows has to stand in front of this position\",\"e_rueckschau_nicht\":\"what follows must not stand in front of this position\",\"e_anzahl\":\"%s times the piece in front\",\"e_anzahl_faul\":\"%s times the piece in front, as few as possible\",\"e_stern\":\"the piece in front, any number of times including none, as many as possible\",\"e_stern_faul\":\"the piece in front, any number of times including none, as few as possible\",\"e_plus\":\"the piece in front, at least once, as many as possible\",\"e_plus_faul\":\"the piece in front, at least once, as few as possible\",\"e_frage\":\"the piece in front, once or not at all\",\"e_frage_faul\":\"the piece in front, preferably not at all\",\"e_anfang\":\"start of the text, or of a line with the m flag\",\"e_ende\":\"end of the text, or of a line with the m flag\",\"e_punkt\":\"any character except a line break, unless the s flag is set\",\"e_oder\":\"or\",\"e_text\":\"the text %s exactly\",\"b_verschachtelt\":\"A quantifier around a group that already holds one can force the engine through an enormous number of combinations. On a non-matching input that takes seconds instead of microseconds.\",\"b_gierig\":\"A greedy dot reaches to the end of the line first and only then works backwards. In most cases a negated character class hits the intended end straight away.\",\"b_ohne_anker\":\"Without an anchor the pattern matches anywhere in the string, so a filter on it also catches the value it was meant to exclude.\",\"b_punkt_unmaskiert\":\"The dot in the pattern is not escaped, so it matches any character. In a domain that turns example.com into a match for examplebcom as well.\",\"b_ohne_g\":\"Without the g flag only the first match is returned, even where the text holds several.\",\"b_umlaute\":\"The class w covers no accented characters. Without the u flag and an explicit range, names with umlauts fall out of the match.\",\"b_ohne_m\":\"The text holds line breaks, but without the m flag the anchors refer to the whole text rather than to each line.\",\"b_kein_treffer\":\"Nothing matched. Where a filter is built on this, it lets everything through or nothing.\"};<\/p>\n<p>    \/\/ --- reine Rechenlogik ---<\/p>\n<p>    const GRENZE_TEXT = 20000;\n    const GRENZE_TREFFER = 500;<\/p>\n<p>    const FLUCHTEN = {\n        'd': 'e_ziffer', 'D': 'e_keine_ziffer', 'w': 'e_wort', 'W': 'e_kein_wort',\n        's': 'e_leer', 'S': 'e_kein_leer', 'b': 'e_grenze', 'B': 'e_keine_grenze',\n        'n': 'e_zeilenumbruch', 't': 'e_tabulator', 'r': 'e_wagenruecklauf'\n    };<\/p>\n<p>    function zerlegen(muster) {\n        \/\/ Der Zerleger geht das Muster einmal durch und beschreibt jedes\n        \/\/ Stueck. Er versteht kein vollstaendiges Regelwerk, aber alles, was\n        \/\/ in einem Muster fuer Auswertung und Filter vorkommt.\n        const stuecke = [];\n        let i = 0;\n        let gruppe = 0;<\/p>\n<p>        function anhaengen(text, schluessel, ersatz) {\n            stuecke.push({ text: text, beschreibung: ersatz === undefined ? T[schluessel] : T[schluessel].replace('%s', ersatz) });\n        }<\/p>\n<p>        while (i < muster.length) {\n            const zeichen = muster.charAt(i);\n\n            if (zeichen === '\\\\') {\n                const naechstes = muster.charAt(i + 1);\n                if (FLUCHTEN[naechstes]) {\n                    anhaengen('\\\\' + naechstes, FLUCHTEN[naechstes]);\n                } else if (\/[0-9]\/.test(naechstes)) {\n                    anhaengen('\\\\' + naechstes, 'e_rueckverweis', naechstes);\n                } else {\n                    anhaengen('\\\\' + naechstes, 'e_woertlich', naechstes);\n                }\n                i += 2;\n                continue;\n            }\n\n            if (zeichen === '[') {\n                let ende = i + 1;\n                if (muster.charAt(ende) === '^') { ende++; }\n                if (muster.charAt(ende) === ']') { ende++; }\n                while (ende < muster.length &#038;&#038; muster.charAt(ende) !== ']') {\n                    if (muster.charAt(ende) === '\\\\') { ende++; }\n                    ende++;\n                }\n                const inhalt = muster.slice(i, ende + 1);\n                anhaengen(inhalt, inhalt.charAt(1) === '^' ? 'e_klasse_nicht' : 'e_klasse', inhalt.slice(inhalt.charAt(1) === '^' ? 2 : 1, -1));\n                i = ende + 1;\n                continue;\n            }\n\n            if (zeichen === '(') {\n                if (muster.substr(i, 3) === '(?:') { anhaengen('(?:', 'e_gruppe_ohne'); i += 3; continue; }\n                if (muster.substr(i, 3) === '(?=') { anhaengen('(?=', 'e_vorschau'); i += 3; continue; }\n                if (muster.substr(i, 3) === '(?!') { anhaengen('(?!', 'e_vorschau_nicht'); i += 3; continue; }\n                if (muster.substr(i, 4) === '(?<=') { anhaengen('(?<=', 'e_rueckschau'); i += 4; continue; }\n                if (muster.substr(i, 4) === '(?<!') { anhaengen('(?<!', 'e_rueckschau_nicht'); i += 4; continue; }\n                if (muster.substr(i, 3) === '(?<') {\n                    const zu = muster.indexOf('>', i);\n                    const name = zu === -1 ? '' : muster.slice(i + 3, zu);\n                    gruppe++;\n                    anhaengen(muster.slice(i, zu + 1), 'e_gruppe_name', name);\n                    i = zu + 1;\n                    continue;\n                }\n                gruppe++;\n                anhaengen('(', 'e_gruppe', String(gruppe));\n                i += 1;\n                continue;\n            }<\/p>\n<p>            if (zeichen === ')') { anhaengen(')', 'e_gruppe_zu'); i += 1; continue; }<\/p>\n<p>            if (zeichen === '{') {\n                const zu = muster.indexOf('}', i);\n                if (zu !== -1 && \/^\\{[0-9]+(,[0-9]*)?\\}$\/.test(muster.slice(i, zu + 1))) {\n                    const inhalt = muster.slice(i + 1, zu);\n                    const faul = muster.charAt(zu + 1) === '?';\n                    anhaengen(muster.slice(i, zu + 1) + (faul ? '?' : ''), faul ? 'e_anzahl_faul' : 'e_anzahl', inhalt);\n                    i = zu + 1 + (faul ? 1 : 0);\n                    continue;\n                }\n            }<\/p>\n<p>            if (zeichen === '*' || zeichen === '+' || zeichen === '?') {\n                const faul = muster.charAt(i + 1) === '?';\n                const schluessel = zeichen === '*' ? 'e_stern' : (zeichen === '+' ? 'e_plus' : 'e_frage');\n                anhaengen(zeichen + (faul ? '?' : ''), faul ? schluessel + '_faul' : schluessel);\n                i += 1 + (faul ? 1 : 0);\n                continue;\n            }<\/p>\n<p>            if (zeichen === '^') { anhaengen('^', 'e_anfang'); i += 1; continue; }\n            if (zeichen === '$') { anhaengen('$', 'e_ende'); i += 1; continue; }\n            if (zeichen === '.') { anhaengen('.', 'e_punkt'); i += 1; continue; }\n            if (zeichen === '|') { anhaengen('|', 'e_oder'); i += 1; continue; }<\/p>\n<p>            \/\/ Mehrere gewoehnliche Zeichen zu einem Stueck zusammenfassen.\n            let ende = i;\n            while (ende < muster.length &#038;&#038; !\/[\\\\\\[\\](){}*+?^$.|]\/.test(muster.charAt(ende))) { ende++; }\n            if (ende === i) { ende = i + 1; }\n            anhaengen(muster.slice(i, ende), 'e_text', muster.slice(i, ende));\n            i = ende;\n        }\n\n        return stuecke;\n    }\n\n    function pruefen(muster, flaggen, text) {\n        const befunde = [];\n\n        if (\/(\\([^)]*[*+][^)]*\\)|\\[[^\\]]*\\][*+])\\s*[*+]\/.test(muster)) {\n            befunde.push({ schwer: true, text: T.b_verschachtelt });\n        }\n        if (muster.indexOf('.*') !== -1 || muster.indexOf('.+') !== -1) {\n            befunde.push({ schwer: false, text: T.b_gierig });\n        }\n        if (muster.indexOf('^') === -1 &#038;&#038; muster.indexOf('$') === -1 &#038;&#038; muster.indexOf('\\\\b') === -1) {\n            befunde.push({ schwer: false, text: T.b_ohne_anker });\n        }\n        if (\/[a-z0-9]\\.[a-z]\/i.test(muster) &#038;&#038; muster.indexOf('\\\\.') === -1) {\n            befunde.push({ schwer: true, text: T.b_punkt_unmaskiert });\n        }\n        if (flaggen.indexOf('g') === -1 &#038;&#038; text.split(\/\\r?\\n\/).length > 1) {\n            befunde.push({ schwer: false, text: T.b_ohne_g });\n        }\n        if (muster.indexOf('\\\\w') !== -1 && flaggen.indexOf('u') === -1) {\n            befunde.push({ schwer: false, text: T.b_umlaute });\n        }\n        if (flaggen.indexOf('m') === -1 && (muster.indexOf('^') !== -1 || muster.indexOf('$') !== -1) && text.indexOf('\\n') !== -1) {\n            befunde.push({ schwer: true, text: T.b_ohne_m });\n        }\n        return befunde;\n    }<\/p>\n<p>    function pruefeMuster(musterRoh, flaggenRoh, textRoh) {\n        const ergebnis = { ok: false, fehler: '', treffer: [], stuecke: [], befunde: [], abgeschnitten: false };\n        const muster = String(musterRoh === undefined || musterRoh === null ? '' : musterRoh);\n        const flaggen = String(flaggenRoh === undefined || flaggenRoh === null ? '' : flaggenRoh).trim();\n        let text = String(textRoh === undefined || textRoh === null ? '' : textRoh);<\/p>\n<p>        if (muster === '') { ergebnis.fehler = T.fehler_leer; return ergebnis; }\n        if (!\/^[gimsuy]*$\/.test(flaggen)) { ergebnis.fehler = T.fehler_flaggen; return ergebnis; }\n        if (text.length > GRENZE_TEXT) {\n            text = text.slice(0, GRENZE_TEXT);\n            ergebnis.abgeschnitten = true;\n        }<\/p>\n<p>        let regex;\n        try {\n            regex = new RegExp(muster, flaggen);\n        } catch (fehler) {\n            ergebnis.fehler = T.fehler_muster.replace('%s', fehler && fehler.message ? fehler.message : '');\n            return ergebnis;\n        }<\/p>\n<p>        ergebnis.stuecke = zerlegen(muster);\n        ergebnis.befunde = pruefen(muster, flaggen, text);<\/p>\n<p>        if (flaggen.indexOf('g') === -1) {\n            const einer = regex.exec(text);\n            if (einer) {\n                ergebnis.treffer.push({ text: einer[0], stelle: einer.index, gruppen: einer.slice(1) });\n            }\n        } else {\n            let treffer;\n            let schutz = 0;\n            regex.lastIndex = 0;\n            while ((treffer = regex.exec(text)) !== null) {\n                ergebnis.treffer.push({ text: treffer[0], stelle: treffer.index, gruppen: treffer.slice(1) });\n                if (treffer[0] === '') { regex.lastIndex++; }\n                schutz++;\n                if (schutz >= GRENZE_TREFFER) { break; }\n            }\n        }<\/p>\n<p>        if (!ergebnis.treffer.length) {\n            ergebnis.befunde.unshift({ schwer: true, text: T.b_kein_treffer });\n        }<\/p>\n<p>        ergebnis.ok = true;\n        return ergebnis;\n    }<\/p>\n<p>    if (typeof window !== 'undefined') {\n        window.LW_TEST = window.LW_TEST || {};\n        window.LW_TEST.RX = { pruefeMuster: pruefeMuster, zerlegen: zerlegen };\n    }<\/p>\n<p>    \/\/ --- Anbindung an das Dokument ---<\/p>\n<p>    const btn = document.getElementById('rx-btn');\n    const out = document.getElementById('rx-ergebnis');\n    if (!btn || !out) { return; }<\/p>\n<p>    const KASTEN = 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-radius: 6px; padding: 14px; margin-bottom: 18px;';\n    const UEBERSCHRIFT = 'color: var(--text-primary, #e8e8ee); font-weight: 700; margin-bottom: 8px;';<\/p>\n<p>    function el(tag, css, inhalt) {\n        const knoten = document.createElement(tag);\n        if (css) { knoten.setAttribute('style', css); }\n        if (inhalt !== undefined && inhalt !== null) { knoten.textContent = inhalt; }\n        return knoten;\n    }<\/p>\n<p>    function wert(id) {\n        const knoten = document.getElementById(id);\n        return knoten ? knoten.value : '';\n    }<\/p>\n<p>    btn.addEventListener('click', function () {\n        const erg = pruefeMuster(wert('rx-muster'), wert('rx-flaggen'), wert('rx-text'));<\/p>\n<p>        out.textContent = '';\n        if (!erg.ok) {\n            out.appendChild(el('div', 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-left: 3px solid #ffb86c; color: var(--text-secondary, #a0a0b0); padding: 14px; border-radius: 6px;', erg.fehler));\n            return;\n        }<\/p>\n<p>        out.appendChild(el('div', UEBERSCHRIFT, T.h_treffer.replace('%s', String(erg.treffer.length))));\n        const kasten = el('div', KASTEN);\n        if (!erg.treffer.length) {\n            kasten.appendChild(el('div', 'color: #ffb86c;', T.keine_treffer));\n        }\n        erg.treffer.forEach(function (t, i) {\n            const z = el('div', 'padding: 6px 0; border-bottom: 1px solid var(--border, #2a2a35);');\n            const kopf = el('div', 'display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap;');\n            kopf.appendChild(el('span', 'width: 30px; color: var(--text-secondary, #a0a0b0); font-family: monospace; font-size: 0.8rem;', String(i + 1)));\n            kopf.appendChild(el('span', 'color: var(--accent, #7ee787); font-family: monospace; word-break: break-all;', t.text));\n            kopf.appendChild(el('span', 'color: var(--text-secondary, #a0a0b0); font-size: 0.78rem;', T.stelle.replace('%s', String(t.stelle))));\n            z.appendChild(kopf);\n            t.gruppen.forEach(function (g, gi) {\n                z.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0); font-family: monospace; font-size: 0.8rem; padding-left: 42px;',\n                    T.gruppe.replace('%n', String(gi + 1)) + ' ' + (g === undefined ? '-' : g)));\n            });\n            kasten.appendChild(z);\n        });\n        if (erg.abgeschnitten) {\n            kasten.appendChild(el('div', 'color: #ffb86c; font-size: 0.85rem; padding-top: 8px;', T.abgeschnitten));\n        }\n        out.appendChild(kasten);<\/p>\n<p>        out.appendChild(el('div', UEBERSCHRIFT, T.h_erklaerung));\n        const erklaerung = el('div', KASTEN);\n        erg.stuecke.forEach(function (s) {\n            const z = el('div', 'display: flex; gap: 14px; align-items: baseline; padding: 5px 0; border-bottom: 1px solid var(--border, #2a2a35);');\n            z.appendChild(el('span', 'min-width: 90px; color: var(--accent, #7ee787); font-family: monospace; font-size: 0.85rem; word-break: break-all;', s.text));\n            z.appendChild(el('span', 'flex: 1; color: var(--text-secondary, #a0a0b0); font-size: 0.87rem;', s.beschreibung));\n            erklaerung.appendChild(z);\n        });\n        out.appendChild(erklaerung);<\/p>\n<p>        if (erg.befunde.length) {\n            out.appendChild(el('div', UEBERSCHRIFT, T.h_befunde));\n            const befunde = el('div', KASTEN);\n            erg.befunde.forEach(function (b) {\n                const z = el('div', 'display: flex; gap: 10px; padding: 5px 0;');\n                z.appendChild(el('span', 'color: ' + (b.schwer ? '#ffb86c' : 'var(--text-secondary, #a0a0b0)') + '; font-family: monospace;', b.schwer ? '!' : '-'));\n                z.appendChild(el('span', 'color: var(--text-secondary, #a0a0b0); font-size: 0.9rem; line-height: 1.5;', b.text));\n                befunde.appendChild(z);\n            });\n            out.appendChild(befunde);\n        }\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Runs a regular expression against a text, lists matches and groups, and explains the pattern piece by piece, including the constructs that make it slow.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":38,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[91297,91144],"class_list":["post-10289","page","type-page","status-publish","hentry","tag-data-quality","tag-devops"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Regex Tester &amp; Explainer - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/regex-tester-explainer\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Regex Tester &amp; Explainer - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Runs a regular expression against a text, lists matches and groups, and explains the pattern piece by piece, including the constructs that make it slow.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/regex-tester-explainer\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/regex-tester-explainer\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/regex-tester-explainer\\\/\",\"name\":\"Regex Tester & Explainer - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-08-14T23:24:10+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/regex-tester-explainer\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/regex-tester-explainer\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/regex-tester-explainer\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Regex Tester &#038; Explainer\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"luky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"luky\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Regex Tester & Explainer - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/regex-tester-explainer\/","og_locale":"en_US","og_type":"article","og_title":"Regex Tester & Explainer - Lukas Wojcik - Blog","og_description":"Runs a regular expression against a text, lists matches and groups, and explains the pattern piece by piece, including the constructs that make it slow.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/regex-tester-explainer\/","og_site_name":"Lukas Wojcik - Blog","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/regex-tester-explainer\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/regex-tester-explainer\/","name":"Regex Tester & Explainer - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-08-14T23:24:10+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/regex-tester-explainer\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/regex-tester-explainer\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/regex-tester-explainer\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/"},{"@type":"ListItem","position":3,"name":"Regex Tester &#038; Explainer"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"luky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"luky"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/10289","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=10289"}],"version-history":[{"count":0,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/10289\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/38"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=10289"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=10289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}