7

In my application, I have an alphanumeric string being passed into my function. This string is typically 17 characters, but not always. I'm trying to write a regex that matches all but the last 4 characters in the string, and replaces them with X (to mask it).

For example

Input: HGHG8686HGHG8686H

Output: XXXXXXXXXXXXX686H

The Regex I wrote to perform the replace on the string is as follows

[a-zA-Z0-9].{12}

Code:

const maskedString = string.replace(/[a-zA-Z0-9].{12}/g, 'X');

The issue I'm having is that it's replacing all but the last 4 characters in the string with just that single X. It doesn't know to do that for every matched character. Any ideas?

2
  • Is there something special you want to do with non-alphanumeric characters? Commented Jul 5, 2017 at 4:24
  • The trick is to use match groups. First match on the last 4 alphanumeric characters, lets call this Group1. Then match on EITHER the START PLUS TWO characters OR any ONE character. Then simply substitute each match with X and append the value of Group1 to the end. Refer my answer below for the regex string. Commented Jul 5, 2017 at 4:34

4 Answers 4

3

you can use a function inside replace to do this, something like this will do:

var str = "HGHG8686HGHG8686H"
var regexp = /[a-zA-Z0-9]+(?=....)/g;
var modifiedStr = str.replace(regexp, function ($2) {
    return ('X'.repeat($2.length +1));
});
console.log(modifiedStr);

Sign up to request clarification or add additional context in comments.

1 Comment

Of 'X'.repeat(...).
2

The simple version: (Easier to read)

const maskedString = string.replace(/(.{4})$|(^(..)|(.))/g, 'X\1'); // or X$1

Now using: [a-zA-Z0-9]

const maskedString = string.replace(/([a-zA-Z0-9]{4})$|(^([a-zA-Z0-9]{2})|([a-zA-Z0-9]{1}))/g, 'X\1'); // or X$1

Note: The reason i match on the START PLUS TWO characters is to offset the first match. (The final 4 characters that are appended at the end.)

Comments

1

Look ahead (?=) to make sure there are at least four following characters.

const regex = /.(?=....)/g;
//             ^             MATCH ANYTHING
//              ^^^^^^^^     THAT IS FOLLOWED BY FOUR CHARS

function fix(str) { return str.replace(regex, 'X'); }

const test = "HGHG8686HGHG8686H";

// CODE BELOW IS MERELY FOR DEMO PURPOSES
const input = document.getElementById("input");
const output = document.getElementById("output");
function populate() { output.textContent = fix(input.value); }
input.addEventListener("input", populate);
input.value = test;
populate();
<p><label>Input: </label><input id="input"></p>
<p>Output: <span id="output"></span></p>

A non-regexp solution:

const test = "HGHG8686HGHG8686H";

function fix(str) {
  return 'X'.repeat(str.length - 4) + str.slice(-4);
}
  
console.log(fix(test));

You will not find String#repeat in IE.

3 Comments

Sir what if we have a some other character other than alphanumeric, this will replace that also. And the question says it replaces all but last 4 and wants to do it for every matching characters. Just a though that struck me. :)
@Manish The question mentions that the input is going to be alphanumeric, but doesn't describe what if anything should be done if characters are not alphanumeric.
This is fantastic. This is the cleanest solution by far.
0

You can achieve using following method:

      var str = "HGHG8686HGHG8686H"

      var replaced=''

      var match = str.match(/.+/)
    
      for(i=0;i<match[0].length-4;i++){
        
          str = match[0][i]
        
          replaced += "X"
        
      }

      replaced += match[0].substr(match[0].length-4)

      console.log(replaced);

2 Comments

in this case suppose i have a special character in the string. So your solution will output the string before that special character only. try with this "HGHG&686HGHG8686H"
But I think replaced += str.replace(/./, "X") is exactly equivalent to replaced += "X".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.