Search code examples
javascriptregexinput-mask

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


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

Solution

  • 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,'');
    }
    

    Update 1: Pasting input that is longer than six characters - i.e. needs to be split more than once - turned out to be problematic with the original answer. An explicit loop is needed as the g modifier does not help with that regex. 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;
    }
    

    Update 2: However, we can get away without an explicit loop with this alternative regex that only uses a single capture - updated fiddle:

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