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!

+3


source to share


4 answers


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 .

+2


source


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);
      

Run codeHide result


+2


source


Use Regex with a trick look ahead

, just find

\d{4}([ -.])(?![A-Za-z])

      

and replace with

****\1

      

0


source


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'));
      

Run codeHide result


0


source







All Articles