Re: regular expression
by moritz (Cardinal) on Feb 15, 2012 at 12:31 UTC
|
use strict;
use warnings;
my $str = '4512872356698';
my $len = length $str;
substr($str, 6, $len - 10) = 'X' x ($len - 10);
print "$str\n";
Using lvalue substr for good effect.
| [reply] [d/l] |
|
| [reply] |
|
substr($str, 6, $len - 10) =~ s/\d/X/g
| [reply] [d/l] |
|
|
Re: regular expression
by JavaFan (Canon) on Feb 15, 2012 at 11:57 UTC
|
s/([0-9]{6})([0-9]+)([0-9]{4})/$1 . ("X" x length $2) . $3/e;
| [reply] [d/l] |
Re: regular expression
by Don Coyote (Hermit) on Feb 15, 2012 at 12:30 UTC
|
As long as the same format of input string is used each time you can use a simple pattern substitution.
Substituting the first part of the number for as many digits as specified, then the middle part for as many digits as specified, and, finally the last part for as many digits as specified. By using the regexp incorporated pattern scalars s/(pat1)(pat2)/$1$2/.
use strict;
my $Number = 4512872356698;
print $Number."\n";
$Number =~ s/^(\d{6})(\d{3})(\d{4})$/$1XXX$3/;
print $Number."\n";
exit 0;
The parentheses denote the pattern relating to the numbered scalar progressively. So the pattern inside the first parenthesis can be called by $1 in the substituting pattern, the pattern inside the second parenthesis can be called by $2 and so on.
Also note JavaFans use of the '+' symbol and the 'X x length' constructs
Coyote | [reply] [d/l] |
Re: regular expression
by trizen (Hermit) on Feb 15, 2012 at 15:58 UTC
|
my $str = '4512872356698';
$str =~ s/^\d{6}\K\d+(?=\d{4})/'X' x ($+[0] - $-[0])/e;
print "$str\n";
Substr:
my $str = '4512872356698';
substr($str, 6, -4, 'X' x (length($str) - 10));
print "$str\n";
| [reply] [d/l] [select] |
Re: regular expression
by AnomalousMonk (Archbishop) on Feb 16, 2012 at 01:18 UTC
|
All other solutions seem to assume that the digit group is alone in a string with the exception of JavaFan's, which, with the addition of the /g modifier, will handle several digit groups embedded in a string.
Here's another solution for handling strings with multiple digit groups. This needs 5.10+ and uses '_' instead of 'X' as the masking character for clarity of result comparison.
>perl -wMstrict -le
"my $start = 6;
my $end = 4;
;;
my $s = '1 123456321 1234564321 '
. '12345654321 123456654321 1234567654321 12345687654321'
;
print qq{'$s'};
;;
$s =~ s{ (?<! \d) \d{$start} \K \d+ (?= \d{$end} (?! \d)) }
{ '_' x length ${^MATCH} }xmsgpe;
print qq{'$s'};
"
'1 123456321 1234564321 12345654321 123456654321 1234567654321 1234568
+7654321'
'1 123456321 1234564321 123456_4321 123456__4321 123456___4321 123456_
+___4321'
| [reply] [d/l] |
Re: regular expression
by sundialsvc4 (Abbot) on Feb 15, 2012 at 14:47 UTC
|
Also consider packages such as Regexp::Common::CC, and others in that very large family of tools. A search for “credit card” at http://search.cpan.org produces 144 promising-sounding hits. If what you are trying to achieve is, as I suspect, “a properly anonymized credit card number,” there is basically a 100% chance that somebody else has already done that.   You can often save a tremendous amount of time by searching CPAN first and frequently, finding off-the-shelf solutions (both large and small) that are both thoroughly tested and comprehensively complete.
| |
Re: regular expression
by ansh batra (Friar) on Feb 15, 2012 at 12:00 UTC
|
$lengeth=length($x)
$temp=substr($x,6) //to get the first six digits
$temp1=substr($x,($length-4),$length) //to get the last 4
for(int i=0;i<($length-10);i++) {
$temp +='X';
}
$temp +=$temp1;
the code is untested and surely contains error.
| [reply] [d/l] |
|
| [reply] |
|
sorry marto
i am in a place where i am not allowed to install any software
missing my perl days very badly
| [reply] |
|