The reason why the code execution hangs is catastrophic backtracking due to one obligatory and 1+ optional patterns (those that can match an empty string) inside a quantified group (\w+'?\s*)+
that allows a regex engine to test a lot of matching paths, so many that it takes too long to complete.
I suggest unwrapping the problematic group in such a way that '
or \s
become obligatory and wrap them in an optional group:
(\w+(?:['\s]+\w+)*)\s*[-~]\s*(\$?\d+(?:\.\d+)?\$?)
^^^^^^^^^^^^^^^^^^^***
See the regex demo
Here, (\w+(?:['\s]+\w+)*)
will match 1+ word chars, and then 0+ sequences of 1+ '
or whitespaces followed with 1+ word chars. This way, the pattern becomes linear and the regex engine fails the match quicker if a non-matching string occurs.
The rest of the pattern:
\s*[-~]\s*
- either -
or ~
wrapped with 0+ whitespaces
(\$?\d+(?:\.\d+)?\$?)
- Group 2 capturing
\$?
- 1 or 0 $
symbols
\d+
- 1+ digits
(?:\.\d+)?
- 1 or 0 zero sequences of:
\.
- a dot
\d+
- 1+ digits
\$?
- 1 or 0 $
symbols