Question: I want to match a number containing 17-23 digits interspersed with spaces or hyphens, then replace all but the last five digits with asterisks. I can match with the following regex:

```
((?:(?:\d)([\s-]*)){12,18})(\d[\s-]*){5}

```

My problem is that I can't get the regex to group all instances of `[\s-]` in the first section, and I have no idea how to get it to replace the initial 12-18 digits with asterisks (`*`).

Answer: 
How about this:

```
s/\d(?=(?:[ -]*\d){5,22}(?![ -]*\d))/*/g

```

The positive lookahead insures that there are at least 5 digits ahead of the just-matched digit, while the embedded *negative* lookahead insures that aren't more than 22.

However, there could still be more digits *before* the first-matched digit. That is, if there are 24 or more digits, this regex only operates on the last 23 of them. I don't know if that's a problem for you.
Even assuming that this is feasible with regex alone I'd bet that it would be way slower than using the non-capturing version of your regex and then reverse iterating over the match, leaving the first 5 digits alone and replacing the rest of them with '\*'.