Regular Expressions Predate the Personal Computer
A pattern that matches cleanly in an online regex tester and then throws an error, or silently matches the wrong thing, in your actual codebase isn't a fluke or a bug in your code. It's the direct result of history that never converged on one standard. Regular expressions feel like a programmer's invention. The actual notation is older than the transistor computer, born in formal logic research with no software in sight.
Born in 1950s mathematical logic, not software
The theoretical foundation for regular expressions comes from Stephen Kleene's work in the 1950s on what he called "regular events," part of automata theory research building on earlier neural-network modeling by Warren McCulloch and Walter Pitts. This was pure formal-logic and computability research. A mathematical notation for describing patterns in sequences, with no programming language or computer text-editing use case anywhere in sight yet.
Ken Thompson turned the theory into working software
In the mid-1960s, Ken Thompson implemented regex matching in the QED text editor, and in 1968 published an algorithm for converting a regular expression directly into a nondeterministic finite automaton (NFA). The technique that made fast, practical regex matching in real software possible. That work fed directly into Unix tools shortly after.
grep's name is a literal fossil of that history
The classic Unix command grep gets its name from a command in the ed text editor: g/re/p, meaning "globally search for a regular expression, and print" the matching lines. The tool that eventually became its own standalone program kept that exact command sequence as its name. A small, well-documented, and genuinely delightful piece of Unix history hiding in plain sight every time someone types "grep" today.
That fossil is also a clue to why regex support today is so uneven: grep, sed, and awk each grew their own slightly different flavor of the notation independently, before there was any shared standard to converge on, so the fragmentation people run into now didn't start with JavaScript or Python. It started decades earlier, tool by tool.
What to actually do when a pattern doesn't port
Different regex "flavors", POSIX, PCRE, and JavaScript's own built-in engine among them. Diverged because each ecosystem added its own extensions over the following decades (lookahead assertions, named capture groups, Unicode property escapes) without ever converging on one unified standard. That's the direct, historical reason a pattern that works perfectly in one language's regex engine can silently behave differently, or fail outright, in another's.
If the goal is writing a pattern once and having it work everywhere, stick to the small common core nearly every engine agrees on: character classes, basic quantifiers, and simple groups, and treat anything fancier (lookbehind, named groups, Unicode property escapes) as engine-specific until proven otherwise. If the goal is just testing a pattern quickly, match the tester's engine to the language you're actually shipping to, since a pattern validated against the wrong flavor can pass in the tester and fail in production.
Test a pattern against your own text with live highlighting using the regex tester.