Weideman's implementation from his MS thesis might be of interest. It handles poly-time regexes as well.
In section 7.2 of this paper I introduced some variants to help with slow analyses
According to the same paper, you can see that problematic worst-case performance can occur in most languages other than Rust and Go (Figure 6).
However, many regex engines have (or are introducing) performance optimizations that address some of these ReDoS issues. So without a dynamic check on the regex's performance, NFA-based analyses can have false positives.
We'll need to implement ReDoS and regex injection queries following up on https://github.com/Semmle/ql/pull/2743