regex replace credit card numbers with *

C

cldmismgr

I have this little piece of code to replace all but the last 4 numbers
in a credit card number with *'s. Is there a better way to do this? I
tried using just a regex but everything I tried failed. For example
s/^[0-9]{9}/*/ replaced this first 9 digits with one *. The idea is to
replace each digit with an asterick and leave the last four digits
alone.
$st = "*";
$addr = '123456789012345';
$size = length($addr) - 4;
for ($i=0;$i < $size; $i++) {
$star .= $st;
}
print "$addr\n";
$addr =~ s/^[0-9]{$size}/$star/;
print "$addr\n$star\n";

Thanks for any comments or advice
Craig
 
A

A. Sinan Unur

I have this little piece of code to replace all but the last 4 numbers
in a credit card number with *'s. Is there a better way to do this? I
tried using just a regex but everything I tried failed. For example
s/^[0-9]{9}/*/ replaced this first 9 digits with one *. The idea is to
replace each digit with an asterick and leave the last four digits
alone.
$st = "*";
$addr = '123456789012345';
$size = length($addr) - 4;
for ($i=0;$i < $size; $i++) {
$star .= $st;
}
print "$addr\n";
$addr =~ s/^[0-9]{$size}/$star/;
print "$addr\n$star\n";

Well, do you just have a string of nine digits, or is there anything
special about the way the credit card number is formatted?

use strict ;
use warnings;

my $cc = '123456789012345';
$cc =~ tr/0123456789/*/;

print "$cc\n";

__END__

perldoc perlop for tr.

Sinan
 
P

Paul Lalli

A. Sinan Unur said:
I have this little piece of code to replace all but the last 4 numbers
in a credit card number with *'s. Is there a better way to do this? I
tried using just a regex but everything I tried failed. For example
s/^[0-9]{9}/*/ replaced this first 9 digits with one *. The idea is to
replace each digit with an asterick and leave the last four digits
alone.
$st = "*";
$addr = '123456789012345';
$size = length($addr) - 4;
for ($i=0;$i < $size; $i++) {
$star .= $st;
}
print "$addr\n";
$addr =~ s/^[0-9]{$size}/$star/;
print "$addr\n$star\n";

Well, do you just have a string of nine digits, or is there anything
special about the way the credit card number is formatted?

use strict ;
use warnings;

my $cc = '123456789012345';
$cc =~ tr/0123456789/*/;

print "$cc\n";

__END__

Er, the output of that code is a series of 15 *'s. Doesn't seem to be
what the OP asked for.
 
P

Paul Lalli

cldmismgr said:
I have this little piece of code to replace all but the last 4 numbers
in a credit card number with *'s. Is there a better way to do this? I
tried using just a regex but everything I tried failed. For example
s/^[0-9]{9}/*/ replaced this first 9 digits with one *. The idea is to
replace each digit with an asterick and leave the last four digits
alone.
$st = "*";
$addr = '123456789012345';
$size = length($addr) - 4;
for ($i=0;$i < $size; $i++) {
$star .= $st;
}

This is just silly. Why are you using an entire for loop just to get a
repeated character?

my $star = '*' x (length ($addr) - 4);
print "$addr\n";
$addr =~ s/^[0-9]{$size}/$star/;

Or, do it all at once:
my $size = length($addr) - 4;
$addr =~ s/^\d{$size}/'*' x $size/e;

Or, if you're can guarantee to yourself that the string will only have
digits to begin with:

substr($addr, 0, $size) = '*' x $size;
print "$addr\n$star\n";

Hope this helps,
Paul Lalli
 
C

cldmismgr

I could not make your first suggestion work. I got the string back
unchanged.
The second one works great for any size string.
New light has been shed on the mysterious regex. For me anyway.
Thanks
 
P

Paul Lalli

Christian said:
cldmismgr said:
I have this little piece of code to replace all but the last 4 numbers
in a credit card number with *'s. Is there a better way to do this? I
tried using just a regex but everything I tried failed. For example
s/^[0-9]{9}/*/ replaced this first 9 digits with one *. The idea is to
replace each digit with an asterick and leave the last four digits
alone.

You could use a look-ahead assertion for that:
$addr =~ s/\d(?=\s{4})/*/g;

Small but significant typo - you want to look for 4 digits remaining,
not spaces.

$addr =~ s/\d(?=\d{4})/*/g;

Paul Lalli
 
T

Tad McClellan

Er, the output of that code is a series of 15 *'s. Doesn't seem to be
what the OP asked for.


So let's fix it with an lvalue substr():

substr($cc, 0, -4) =~ tr/0-9/*/;
 
P

Paul Lalli

Tad said:
an lvalue substr():

substr($cc, 0, -4) =~ tr/0-9/*/;

Ooh, I like! I was trying to think of a good way of doing this with
substr, but I was blanking on remembering the "negative limit" feature
of the function.

Thanks, Tad.

Paul Lalli
 
A

axel

cldmismgr said:
I have this little piece of code to replace all but the last 4 numbers
in a credit card number with *'s. Is there a better way to do this? I
tried using just a regex but everything I tried failed. For example
s/^[0-9]{9}/*/ replaced this first 9 digits with one *. The idea is to
replace each digit with an asterick and leave the last four digits
alone.
$st = "*";
$addr = '123456789012345';
$size = length($addr) - 4;
for ($i=0;$i < $size; $i++) {
$star .= $st;
}
print "$addr\n";
$addr =~ s/^[0-9]{$size}/$star/;
print "$addr\n$star\n";

One solution would be as follows - note also allows for non-digits
to be interspersed (and ignored).

#!/usr/bin/perl

use strict;
use warnings;

my $st = "*";
my $addr = '1245-4536-8904-2345';
print $addr, "\n";

$addr =~ s/\d/$st/ for (1 .. ($addr =~ tr/0-9//) - 4);

print $addr, "\n";

__END__

Output:

1245-4536-8904-2345
****-****-****-2345

Axel
 
A

A. Sinan Unur

A. Sinan Unur said:
I have this little piece of code to replace all but the last 4
numbers in a credit card number with *'s. Is there a better way to
do this? I tried using just a regex but everything I tried failed.
For example s/^[0-9]{9}/*/ replaced this first 9 digits with one *.
The idea is to replace each digit with an asterick and leave the
last four digits alone.
$st = "*";
$addr = '123456789012345';
$size = length($addr) - 4;
for ($i=0;$i < $size; $i++) {
$star .= $st;
}
print "$addr\n";
$addr =~ s/^[0-9]{$size}/$star/;
print "$addr\n$star\n";

Well, do you just have a string of nine digits, or is there anything
special about the way the credit card number is formatted?

use strict ;
use warnings;

my $cc = '123456789012345';
$cc =~ tr/0123456789/*/;

print "$cc\n";

__END__

Er, the output of that code is a series of 15 *'s. Doesn't seem to be
what the OP asked for.

Sorry, I missed that part.

One way to do that with the substitution operator is:

use strict ;
use warnings;

my $cc = '123456789012345';
$cc =~ s/\d{11}(?=\d{4})/('*') x 11/e;

print "$cc\n";

__END__

D:\Home\asu1\UseNet\clpmisc> c
***********2345

Sinan

PS: I am assuming that the OP incorrectly stated that he wanted replace
the first 9 digits and leave the last four alone because the string
contains 15 characters.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top