Port away from QRegExp
There's two unusual things here:
- All expressions are fully anchored, making the old exactMatch() and match() equivalent.
- capturedTexts() no longer contains empty strings for optional capture groups, so the list size can vary. Using captured() instead does what we need and even avoids the temporary list.