Home > database >  regex for input mask - comma separated list of up to three characters per item
regex for input mask - comma separated list of up to three characters per item

Time:09-28

I have an input field, which I want to limit as follows:

  1. The input will be a comma-separated list
  2. Each string in the list must be limited to 1..3 characters
  3. The list can have as many items as the user wants

some examples:

1,4,6a,16b
1
abc,def,ghi,jkl,mno,pqr,stu,vwx,yzz

I have found the following jsfiddle: https://jsfiddle.net/2x8y1dhL/ which provides a starting point for creating an input mask, but it assumes a fixed number of items in the list, and a fixed length of each input.

What I want is the following logic:

  • after the user inputs the third character in a row that isn't a comma, a comma is automatically inserted

CodePudding user response:

I have worked on the jsfiddle you have found. Some notes:

  • You have not specified valid/invalid characters, but the examples given seem to suggest "alpha-numeric plus comma"
  • Consecutive commas are allowed as it's not specified otherwise.

The meat of the matter are the two functions createMask and destroyMask:

function createMask(string){
    return string.replace(/(\w{3})(?!,)(. )$/g,"$1,$2");
}

function destroyMask(string){
    return string.replace(/[^0-9A-Z,]/ig,'');
}

Hope that helps!


If you want to support long pasted input, this regex needs to be put in an explicit loop, as the g modifier alone can't cut it in this situation. Here's the updated fiddle:

function createMask(string){
  let s = string;
  let t;
  do {
    t = s;
    s = s.replace(/(\w{3})(?!,)(. )$/,"$1,$2");    
  } while (s !== t)
  return s;
}

Alternatively, we can get away without loop with this regex that only uses a single capture:

function createMask(string){
    return string.replace(/(\w{3})(?!,|$)/g,"$1,");
}

CodePudding user response:

You can repeat optional repetitions of 3 word characters followed by a comma and then match 3 word characters asserting a word char to the right.

^(?:\w{3},)*\w{3}(?=\w)

Regex demo | Forked fiddle

In the replacement use the full match $& followed by a comma.

$("input[name='masknumber']").on("input", function(){
  let n = destroyMask(this.value);
    this.setAttribute("data-normalized", n);
  this.value = createMask(n);
})

function createMask(string){
    return string.replace(/^(?:\w{3},)*\w{3}(?=\w)/g,"$&,");
}

function destroyMask(string){
    return string.replace(/[^0-9A-Z,]/ig,'');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" name="masknumber" data-normalized="" size=64>

Or fiddle demo with a variant with 2 capture groups.

  • Related