Regex Tester

Test regular expressions in real-time with flag toggles, match highlighting, and capture group display.

Developer
100% Free
Runs in Browser

Preview

Source Code

Toggle the controls below the code to live-edit the initial state values.

regex-tester.tsx
import { useState, useMemo } from "react";
import { Textarea } from "@/components/ui/textarea";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";

export default function RegexTester() {
    const [pattern, setPattern] = useState("(\\w+)@(\\w+\\.\\w+)");
    const [flags, setFlags] = useState("gi");
    const [testString, setTestString] = useState(
        "Contact us at hello@example.com or support@test.org for more info."
    );

    const { matches, error } = useMemo(() => {
        try {
            const regex = new RegExp(pattern, flags);
            const results: { match: string; index: number; groups: string[] }[] = [];
            let m: RegExpExecArray | null;

            if (flags.includes("g")) {
                while ((m = regex.exec(testString)) !== null) {
                    results.push({
                        match: m[0],
                        index: m.index,
                        groups: m.slice(1),
                    });
                    if (!m[0]) break; // prevent infinite loop on zero-width matches
                }
            } else {
                m = regex.exec(testString);
                if (m) {
                    results.push({
                        match: m[0],
                        index: m.index,
                        groups: m.slice(1),
                    });
                }
            }

            return { matches: results, error: "" };
        } catch (e: any) {
            return { matches: [], error: e.message };
        }
    }, [pattern, flags, testString]);

    const flagOptions = [
        { flag: "g", label: "Global" },
        { flag: "i", label: "Case Insensitive" },
        { flag: "m", label: "Multiline" },
        { flag: "s", label: "Dotall" },
    ];

    const toggleFlag = (f: string) => {
        setFlags((prev) => (prev.includes(f) ? prev.replace(f, "") : prev + f));
    };

    return (
        <div className="space-y-4">
            <div className="flex flex-col sm:flex-row gap-3">
                <div className="flex-1">
                    <label className="text-sm font-medium text-muted-foreground mb-1 block">
                        Pattern
                    </label>
                    <div className="flex items-center gap-1 rounded-lg border px-3 py-1.5 font-mono text-sm">
                        <span className="text-muted-foreground">/</span>
                        <input
                            type="text"
                            value={pattern}
                            onChange={(e) => setPattern(e.target.value)}
                            className="flex-1 bg-transparent outline-none"
                            placeholder="your regex here"
                        />
                        <span className="text-muted-foreground">/</span>
                        <span className="text-primary">{flags}</span>
                    </div>
                </div>
            </div>

            <div className="flex flex-wrap gap-2">
                {flagOptions.map((opt) => (
                    <button
                        key={opt.flag}
                        onClick={() => toggleFlag(opt.flag)}
                        className={`rounded-md border px-2.5 py-1 text-xs font-medium transition-colors ${flags.includes(opt.flag)
                                ? "bg-primary text-primary-foreground border-primary"
                                : "border-border text-muted-foreground hover:bg-muted"
                            }`}
                    >
                        {opt.flag} — {opt.label}
                    </button>
                ))}
            </div>

            <div>
                <label className="text-sm font-medium text-muted-foreground mb-1 block">
                    Test String
                </label>
                <Textarea
                    value={testString}
                    onChange={(e) => setTestString(e.target.value)}
                    className="min-h-[100px] resize-y text-sm"
                    placeholder="Enter text to test against..."
                />
            </div>

            {error && (
                <div className="rounded-lg border border-destructive/50 bg-destructive/10 p-3">
                    <p className="text-sm text-destructive font-mono">{error}</p>
                </div>
            )}

            <div className="rounded-lg border p-3">
                <div className="flex items-center gap-2 mb-2">
                    <span className="text-sm font-medium">Matches</span>
                    <Badge variant="secondary">{matches.length}</Badge>
                </div>
                {matches.length === 0 && !error ? (
                    <p className="text-sm text-muted-foreground">No matches found</p>
                ) : (
                    <div className="space-y-2">
                        {matches.map((m, i) => (
                            <div key={i} className="rounded border bg-muted/50 px-3 py-2 text-sm font-mono">
                                <div className="flex items-center gap-2 flex-wrap">
                                    <Badge variant="outline" className="text-xs">#{i + 1}</Badge>
                                    <span className="text-primary font-semibold">{m.match}</span>
                                    <span className="text-muted-foreground text-xs">at index {m.index}</span>
                                </div>
                                {m.groups.length > 0 && (
                                    <div className="mt-1 flex flex-wrap gap-1">
                                        {m.groups.map((g, gi) => (
                                            <Badge key={gi} variant="secondary" className="text-xs">
                                                ${gi + 1}: {g}
                                            </Badge>
                                        ))}
                                    </div>
                                )}
                            </div>
                        ))}
                    </div>
                )}
            </div>
        </div>
    );
}
Props Playground
2 props

Required Libraries

Install the external dependencies used by this tool.

bun add react

Shadcn UI Setup

Add the required Shadcn UI primitives to your project.

bun x --bun shadcn@latest add badge input textarea

Shadcn UI Components

The following primitives are required in your @/components/ui directory.

Component Import Path
badge @/components/ui/badge
input @/components/ui/input
textarea @/components/ui/textarea

Imports

All import statements used in this tool.

Source Exports
react useState, useMemo
@/components/ui/textarea Textarea
@/components/ui/input Input
@/components/ui/badge Badge

State Management

React state variables managed within this tool.

Variable Initial Value
pattern "(\\w+
flags "gi"
testString "Contact us at hello@example.com or support@test.org for more info."

Variables & Constants

Constants and computed values defined in this tool.

Name Value
regex new RegExp(pattern, flags)
results []
flagOptions [

Functional Logic

Internal functions that handle the tool's core logic.

Function Parameters Async
toggleFlag() f: string No

External Resources

Documentation, tutorials, and package details for libraries used in this tool.