3

I am trying to convert regular expression format into a mask-input string to guide the user to enter the correct input on the UI. Numbers would be represented by "#" and letter by "A".

Basically,

      "^\d{3}$"                        -->    "###"
      "^(GB)\d{3}$"                    -->    "GB###"
      "^\d{2}\.\d{3}\/\d{4}-\d{2}$"    -->    "##.###/####-##"
      "^\d{2}[ ]\d{3}[ ]\d{3}$"        -->    "## ### ###" 

function convertToMaskInput(regex){

}

convertToMaskInput("^\d{4}$");
//Output: "####"

I am beginner to Javascript and I am having hard time to do this dynamically. Any help or guidance is appreciated.

Thanks in advance!

4
  • This is a hard task, especially for a begginer. You'd better use a library like digitalbush.com/projects/masked-input-plugin or something Commented Mar 27, 2017 at 23:11
  • No practical coding solution would cover all regular expressions. If you have a small set of same, you could just do it manually. Otherwise you'd have to make an awful lot of assumptions. Many regular expressions match an infinite number of possibilities - making this problem essentially intractable. Commented Mar 27, 2017 at 23:12
  • If you have a known input format you're testing (converting?), there is no problem doing this. /^\d{3}$/ --> "###" /^(GB)\d{3}$/ --> "GB###" /^\d{2}\.\d{3}\/\d{4}-\d{2}$/ --> "##.###/####-##" /^\d{2}[ ]\d{3}[ ]\d{3}$/ --> "## ### ###" Commented Mar 27, 2017 at 23:22
  • I guess he wants to generate the format from the given regex like some MaskedInput-components are capable of doing. Commented Mar 28, 2017 at 0:02

1 Answer 1

2

If your goal is to handle every possible variant of regular expression, you should probably use an existing plugin rather than rolling your own solution.

However, for the sake of completeness, here is an implementation that can deal with the subset of cases you gave as examples:

function convertToMaskInput(regex) {
  return new RegExp(regex).source
    .replace(/^\^|\$$/g, '')
    .replace(/\\d/g, '#')
    .replace(/\(([^)]*)\)|\[([^^])\]|\\([\\/.(){}[\]])/g, '$1$2$3')
    .replace(/([\w#.-])\{(\d+)\}/gi, function (_, c, n) {
        return Array(+n + 1).join(c)
    })
}

convertToMaskInput("^\d{4}$")

console.log([
  /^\d{3}$/, //=> "###"
  /^(GB)\d{3}$/, //=> "GB###"
  /^\d{2}\.\d{3}\/\d{4}-\d{2}$/, //=> "##.###/####-##"
  /^\d{2}[ ]\d{3}[ ]\d{3}$/ //=> "## ### ###" 
].map(convertToMaskInput))

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

2 Comments

Thank you for your response. Do you mind explaining what 3rd and 4th replace statements pls ?
Third replace statement replaces matching groups (...) with their contents and removes the brackets around single-character character sets, as well as unescaping literals like \\( and \\[ within your regex. The fourth replace statement is used to repeat characters followed by a matching range (#{4} becomes ####).

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.