Skip to content

Regex Tester — Java source

Test regular expressions against any text with all flags (g/i/m/s/u/y). See every match, its index and capture groups, plus the constructed pattern. 100% in-browser.

This is the Java implementation — the same logic the interactive tool runs, in a shareable, citable form.

// regex-tester — Java port. Match a pattern against text, report every match
// with capture groups and index (java.util.regex).
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class RegexTester {
    record RegexMatch(String match, int index, List<String> groups) {}

    // JS flag letters -> Pattern bits. g selects all matches; u is the
    // default for String patterns; y has no equivalent.
    static int compileFlags(String flags) {
        int f = 0;
        for (char c : flags.toCharArray())
            f |= c == 'i' ? Pattern.CASE_INSENSITIVE
               : c == 'm' ? Pattern.MULTILINE
               : c == 's' ? Pattern.DOTALL : 0;
        return f;
    }

    static List<RegexMatch> runRegex(String pattern, String flags, String text) {
        List<RegexMatch> out = new ArrayList<>();
        try {
            Matcher m = Pattern.compile(pattern, compileFlags(flags)).matcher(text);
            int limit = flags.contains("g") ? 2000 : 1;
            while (m.find() && out.size() < limit) {
                List<String> groups = new ArrayList<>();
                for (int g = 1; g <= m.groupCount(); g++)
                    groups.add(m.group(g) == null ? "" : m.group(g));
                out.add(new RegexMatch(m.group(), m.start(), groups));
                if (m.end() == m.start()) {           // zero-width match:
                    if (m.end() == text.length()) break;
                    m.region(m.end() + 1, text.length()); // advance manually
                }
            }
        } catch (PatternSyntaxException e) {
            System.err.println("error: " + e.getMessage());
        }
        return out;
    }

    // Render a result the way the tool's UI does:
    // `N. "match" @ index -> [g1, g2]`, or `(none)` when empty.
    static String formatMatches(List<RegexMatch> ms) {
        if (ms.isEmpty()) return "(none)";
        var lines = new ArrayList<String>();
        for (int i = 0; i < ms.size(); i++) {
            RegexMatch m = ms.get(i);
            String line = (i + 1) + ". \"" + m.match() + "\" @ " + m.index();
            if (!m.groups().isEmpty()) line += " -> [" + String.join(", ", m.groups()) + "]";
            lines.add(line);
        }
        return String.join("\n", lines);
    }

    public static void main(String[] args) {
        System.out.println(formatMatches(
            runRegex("(\\w+)@(\\w+)\\.(\\w+)", "g", "mail@x.com nope bob@test.org")));
    }
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →