admin管理员组

文章数量:1200423

I'm trying to mask a portion of a string using JavaScript.

e.g. Mask second and third segment of credit-card number like this using regex:

  • 4567 6365 7987 37834567 **** **** 3783
  • 3457 732837 823723457 ****** 82372

I just want to keep the first 4 numbers and the last 5 characters.

This is my first attempt: /(?!^.*)[^a-zA-Z\s](?=.{5})/g

I'm trying to mask a portion of a string using JavaScript.

e.g. Mask second and third segment of credit-card number like this using regex:

  • 4567 6365 7987 37834567 **** **** 3783
  • 3457 732837 823723457 ****** 82372

I just want to keep the first 4 numbers and the last 5 characters.

This is my first attempt: /(?!^.*)[^a-zA-Z\s](?=.{5})/g

https://regex101.com/r/ZBi54c/2

Share Improve this question edited Apr 20, 2017 at 16:34 Mr. Polywhirl 48.6k12 gold badges93 silver badges144 bronze badges asked Apr 20, 2017 at 16:18 Josue SorianoJosue Soriano 1231 gold badge1 silver badge6 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 11

You can try this:

var cardnumber = '4567 6365 7987 3783';
var first4 = cardnumber.substring(0, 4);
var last5 = cardnumber.substring(cardnumber.length - 5);

mask = cardnumber.substring(4, cardnumber.length - 5).replace(/\d/g,"*");
console.log(first4 + mask + last5);

You could slice the first four digits and apply a replacement for the rest.

console.log(
    ['4567 6365 7987 3783', '3457 732837 82372'].map(
        s => s.slice(0, 4) + s.slice(4).replace(/\d(?=.* )/g, '*')
    )
);

The answer apparently satisfies the OP. Here is another solution using only Regexes:

function starry(match, gr1, gr2, gr3) {
  var stars = gr2.replace(/\d/g, '*');
  return gr1 + " " + stars + " " + gr3;
}

function ccStarry(str) {
  var rex = /(\d{4})\s(\d{4}\s\d{4}|\d{6})\s(\d{4}|\d{5})/;

  if (rex.test(str))
    return str.replace(rex, starry);
  else return "";
}


var s1 = "4567 6365 7987 3783";
var s2 = "3457 732837 82372";
var s3 = "dfdfdf";
console.log(ccStarry(s1));
console.log(ccStarry(s2));
console.log(ccStarry(s3));

This ensures that the pattern matches before trying any replacements. For example, in the third test case, it returns an empty string. The pattern can be updated to match other credit card patterns besides the ones given in the question.

I would like to elaborate more on the answer from @Nina Scholz, I use .slice() in the following sample code for masking the variable in 2 condition.

  1. Just a simple variable var n = '12345567890'
  2. Array object

// Single number
var n = '601115558888';
var singleNumber = n.slice(0, 4) + n.slice(4, n.length -4).replace(/\d/g,'*') + n.slice(n.length -4);
console.log(singleNumber);

// array of object
var obj = [{
  contacts_name: 'Jason',
  contacts_num : '651231239991'
},
{
  contacts_name: 'King',
  contacts_num : '60101233321'
}];

// Mask for the middle number, showing the first4 number and last4 number
// and replace the rest number with *
var num = obj.map((element, index) =>
  element.contacts_num.slice(0,4) 
   + element.contacts_num.slice(4, element.contacts_num.length-4).replace(/\d/g, '*')
   + element.contacts_num.slice(element.contacts_num.length -4)
);

console.log(num);

If it's JavaScript doing the regex masking, you've already failed because JS should never need to know the original card number, except when you've just received it from the user and are sending it to the server for the first time, in which case you shouldn't be masking it anyway so the user can check for typos.

I can't really help you there, you've already failed in the worst way.

Server-side, if the number is already broken into spaces*, then one option is: (in PHP but the same idea applies to all)

$parts = explode(" ",$fullnumber);
$first = array_shift($parts);
$last = array_pop($parts);
$middle = implode(" ",$parts);
$mask = preg_replace("/\d/","*",$middle);
$result = "$first $mask $last";

* it shouldn't be

本文标签: javascriptMask a portion of a String using RegExpStack Overflow