Javascript - masking account number in string
I have an interesting challenge that I could not find an answer to. I have a line of text that could potentially contain an account number. Example:
"Hi, my account number is 1234 5678 9012 2345 and I'm great."
The account number can come in many variations as it is entered by the user:
The main and potential features are below:
1234 1234 1234 1234
1234 1234 1234 1234 1
BE12 1234 1234 1234
1234-1234-1234-1234
1234.1234.1234.1234
1234123412341234
12341234 1234 1234
1234-1234-1234-1234-1
1234.1234.1234.1234.1
12341234123412341
12341 234 1234 12341
BE12-1234-1234-1234
be12-1234-1234 1234
Be12.1234.1234-1234
BE12123412341234
(mostly integers with a hyphen, space or dot in the middle, except for the IBAN format, which has two characters at the beginning)
What I need for output, everything is masked except for the last four digits.
"Hi, my account number is **** **** **** 2345 and I'm great."
The way I think I should approach this problem:
- Analyze each line and try to find the above account. templates
- Create a magic regex that replaces account no. I need them
- If there is an account number, use this RegEx for that.
What is your approach?
Thank!
source to share
You can match all of the above with:
\b[\dX][-. \dX]+(\d{4})\b
... and replace it with *
x strlen(match) - 4
+ \1
, see demo at regex101.com .
In
JavaScript
:
var string = "Hi, my account number is 1234 5678 9012 2345 and I'm great.";
var new_string = string.replace(/\b[\dX][-. \dX]+(\d{4})\b/g, function(match, capture) {
return Array(match.length-4).join("*") + capture;
});
print(new_string);
See the demo at ideone.com .
source to share
Borrowing Jan's awesome regex pattern, it can be extended to capture the last digit (see example below)
Note: Its method of use is replace()
better, I recommend using it for clarity. This can only suggest an alternative approach usingmatch()
// Setup
let str = `1234 1234 1234 1234
1234-1234-1234-1234
12341234123412341234
1234 1234 1234 1234 1
12341234123412341
1234-1234-1234-1234-1
1234.1234.1234.1234.1
XX12 3456 1234 1234
XX123456123123
XX12-3456-1234-1234
XX12.3456.1234.1234
This is a sentence for visual proof 1234 5678 9012 3456
And some XX32 1111.2222-9999-2 more proof`,
nums = str.split('\n');
var re = new RegExp(/(\b[\dX][-. \dX]+(\d{4}.?\d?)\b)/);
// Convert Nums
var converted = nums.map(num => {
let match = num.match(re);
if (match) {
let orig = match[1],
end = match[2],
hidden = orig.substr(0, orig.length - end.length);
hidden = hidden.replace(/\S/g, "X") + end;
num = num.replace(orig, hidden);
}
return num;
});
// Visual Verification
console.log(converted);
source to share
str.replace(/\b[\dX][-. \dX]+(\d{4})\b/g, '**** **** **** $1')
console.log("Hi, my account number is 1234-5678-9012-2345 and I'm great.".replace(/\b[\dX][-. \dX]+(\d{4})\b/g, '**** **** **** $1'));
console.log("Hi, my account number is 1234 5678 9012 2345 and I'm great.".replace(/\b[\dX][-. \dX]+(\d{4})\b/g, '**** **** **** $1'));
console.log("Hi, my account number is 1234.5678.9012.2345.1 and I'm great.".replace(/\b[\dX][-. \dX]+(\d{4})\b/g, '**** **** **** $1'));
console.log("Hi, my account number is XX123456123123 and I'm great.".replace(/\b[\dX][-. \dX]+(\d{4})\b/g, '**** **** **** $1'));
source to share