59

I am trying to validate input type="text" using a pattern. I want text only.

Component :

 this.from = this.fb.group({
  name: ['',[Validators.required,Validators.pattern('/^[a-zA-Z]+$/')]],

});

Html :

<input type="text" formControlName="name"/> // omitting other html template like from tag.

The above pattern validation is not working for me. It always returns an invalid state.

2
  • 6
    What happens if you really pass a regexp, rather than a string: pattern(/^[a-zA-Z]+$/)? Commented Feb 22, 2017 at 13:15
  • 2
    Either that or Validators.pattern('^[a-zA-Z]+$') Commented Feb 22, 2017 at 13:25

10 Answers 10

87

Pass pattern as string, without / which are the delimiters for regex

Validators.pattern('^[a-zA-Z]+$')
Sign up to request clarification or add additional context in comments.

5 Comments

'pin_code': ['', [ Validators.required, Validators.pattern('^[0-9]{1,6}$') ]],
REGEXP is not working is above example of my angular 4 project...just required is working from givin conditions
@Günter Zöchbauer Any idea why formControl.hasError('pattern') is giving false even though I have defined it?
@Krishna perhaps better to create a new question with a StackBlitz example that demonstrates the issue.
@Günter Zöchbauer Issue is it somehow works on stackblitz but not vscode. this.formControl = new FormControl('', [ Validators.required, Validators.bind(this.validateIds), Validators.pattern(/ somepatter''/) ]); console.log(this.formControl.errors) gives only {required: true}
44

Remember to not do this:

Validators.pattern("[A-Z]{1,2}[0-9][0-9A-Z]?\s?[0-9][A-Z]{2}")

The gotcha is that you need a double backslash before the s to defeat string escape thus:

Validators.pattern("[A-Z]{1,2}[0-9][0-9A-Z]?\\s?[0-9][A-Z]{2}")

2 Comments

how on earth did you know that? so only space should be double escaped? Not dot, commas?
What's happening is that you've got two layers of escaping, one in Javascript strings, and another in regular expressions. The problem is with the Javascript escaping where \ precedes a special character in a string: you avoid this by telling the JS string you actually want a backslash character by using \\. This then gets passed down to the regular expression properly.
33

I had this same problem with a different pattern:

^\d{1,4}$

And I was using it like this:

Validators.pattern("^\d{1,4}$") // wrong

The problem is that the backslash \ has to be escaped, so the correct form is:

Validators.pattern("^\\d{1,4}$") // correct

Comments

18
emailRegex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
this.form = fb.group({
      Email : new FormControl({value: null}, Validators.compose([
        Validators.required,
        Validators.pattern(this.emailRegex)]))
});

2 Comments

Good answer, although it should be updated to allow for longer domain suffixes
Just a side note here: for validating email addresses, just use the built-in Validators.email instead of your own regexp. But in terms of illustrating that regexp literals (or variable references to them) can be passed, this answer is correct.
17

This is what I've found when using Validators.pattern():

Works

Validators.pattern('[a-z]{2}')
Validators.pattern(/^[a-z]{2}$/)

Doesn't work

Validators.pattern(/[a-z]{2}/i)
Validators.pattern(/[a-z]{2}/)

Comments

6

You can pass the validator as string or regex, both work if you do it correctly. Let's consider the requirement text only:

As regex

const regex = /[a-zA-Z]*/;
let formControl = new FormControl('', Validators.pattern(regex));

In a FormControl, the validator will set state VALID if any matches to the regex are found (substrings). Therefore we need to specify the beginning and end of the input to enforce exact matches, by ^ and $:

const regex = /^[a-zA-Z]*$/;

This will return VALID for single words, which satisfies the OPs requirement. However, it will return INVALID for longer text containing whitespace, commas, punctuations and hyphens. So if we want, we can add those to the character set:

const regex = /^[a-zA-Z,.\s-]*$/;

Since we are working with a regex, we can simplify the character set by setting the i flag at the end. This tells the regex to ignore case-sensitivity, so it's enough with only one of the character ranges:

const regex = /^[a-z,.\s-]*$/i;

The above regex will be VALID for any text containing UPPER-CASE, lower-case, whitespaces, punctuation and commas. If you want to accept exclamation marks and questions marks as well, simply add them to the character set:

const regex = /^[a-z,.!?\s-]*$/i;

As string

When passing the validator expression as a string, you do not use the regex delimiters / /, and cannot pass regex flags. As a consequence, we have to include both UPPER and lower case characters in the set. As others point out, you also have to escape any backward slashes in a string.

The equivalent validator as a string would look like this:

const validatorString = '^[a-zA-Z,.!?\\s-]*$';
let formControl = new FormControl('', Validators.pattern(validatorString));

Note that if you leave out the ^ and $ when the expression is passed as a string, Angular will automatically add them when processing the validator. That's why passing the expression as a string often appears to work better than regex. Personally, I prefer regex over string.

To better understand the concepts of Regular Expressions, I highly recommend this website: https://regexr.com/

Comments

1

Text + 'space'

Validators.pattern('[a-zA-Z ]*')

Comments

1

I've tried using the Validators.pattern with a regex string like this

Validators.pattern('[A-Za-z]{6}') // Didn't work

But when I was reading the docs, I've noticed that If a string is passed, the ^ character is prepended and the & character is appended to the provided string (if not already present)

enter image description here

This is what worked for me

Validators.pattern('^[A-Za-z]{6}$')

Comments

0

You do not need string in Validator.pattern. You can either use string or regex expression directly. See:enter image description here

Comments

0

I also had problem converting from c# to angular. You need an extra backslash on the \d but not on the regular escaped characters.

ValidationExpression="[\d|\*|w|#]{0,25}"

to

Validators.pattern('[\\d|*|w|#]{0,25}')

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.