  Existing support for regular expressions in automated test generation or
verification tools is lacking. Common aspects of regular expression engines
found in mainstream programming languages, such as backreferences or greedy
matching, are commonly ignored or imprecisely approximated, leading to poor
test coverage or failed proofs. In this paper, we present the first complete
strategy to faithfully reason about regular expressions in the context of
symbolic execution, focusing on the operators found in JavaScript. We model
regular expression operations using string constraints and classical regular
expressions and use a refinement scheme to address the problem of matching
precedence and greediness. Our survey of over 400,000 JavaScript packages from
the NPM software repository shows that one fifth make use of complex regular
expressions features. We implemented our model in a dynamic symbolic execution
engine for JavaScript and evaluated it on over 1,000 Node.js packages
containing regular expressions, demonstrating that the strategy is effective
and can increase line coverage of programs by up to 30%
