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.
I think your regex is ok, but you might need to have a callback where you can insert the asterisks with another inline regex. The below is a Perl example.

`s/((?:\d[\s-]*){12,18})((?:\d[\s-]*){4}\d)/ add_asterisks($1,$2) /xeg`

```
use strict;
use warnings;

my $str = 'sequence of digits 01-2  3-456-7-190 123-416 78 ';

if ($str =~ s/((?:\d[\s-]*){12,18})((?:\d[\s-]*){4}\d)/ add_asterisks($1,$2) /xeg )
{
   print "New string: '$str'\n";
}

sub add_asterisks {
   my ($pre,$post) = @_;
   $pre =~ s/\d/*/g;
   return $pre . $post;
}

__END__

```

Output

`New string: 'sequence of digits **-* *-***-*-*** ***-416 78 '`