angular: Problem with pattern validation

I’m submitting a …

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

I’m doing a pattern validation related to a field named “email”, checking this pattern “^[a-z0-9]+(.[_a-z0-9]+)@[a-z0-9-]+(.[a-z0-9-]+)(.[a-z]{2,15})$”

It works most times… but when I type “adfsaf@dafsdfcom” it match the pattern… but it should not match

Expected behavior I’m checking the regex “^[a-z0-9]+(.[_a-z0-9]+)@[a-z0-9-]+(.[a-z0-9-]+)(.[a-z]{2,15})$” in the page: https://regex101.com/

When I check the previous example “adfsaf@dafsdfcom” it doesnt match the pattern… but in Angular 2 it match the pattern

Minimal reproduction of the problem with instructions this is my code in the the x.component.ts

this.myForm = new FormGroup({
            nombre: new FormControl('', [<any>Validators.required ]),
            email: new FormControl('', [<any>Validators.pattern("^[a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,15})$") ]),
        });

This is my code in the x.component.ts <form [formGroup]=“myForm” novalidate (ngSubmit)=“save(myForm.value, myForm.valid)”> <div class="form-group"> <label for="nombre">Nombre completo</label>

                <small [hidden]="myForm.controls.nombre.valid || (myForm.controls.nombre.pristine && !submitted)">
                    Nombre es obligatorio
                </small>
            </div>
            <div class="form-group col-md-6">
                    <label for="email">Email</label>
                    <input type="text" class="form-control" formControlName="email">
                <small [hidden]="myForm.controls.email.valid || (myForm.controls.email.pristine && !submitted)">
                    Campo invalido
                </small>
            </div>
</form>

What is the motivation / use case for changing the behavior?

Please tell us about your environment: Ubuntu 16.04 Visual studio code

  • Angular version: 2.4.0

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ] Google Chrome Version 54.0.2840.100 (64-bit)

  • Language: [TypeScript 2.0.10 ]

  • Node (for AoT issues): node --version = 7.2.1

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 19 (5 by maintainers)

Most upvoted comments

@vihuarar please try to pass /^[a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,15})$/ instead of string

@vihuarar i extracted code that builds pattern in angular 2.4.0:

function buildPattern(pattern) {
  let regex;
  let regexStr;

  if (typeof pattern === 'string') {
    regexStr = `^${pattern}$`;
    regex = new RegExp(regexStr);
  } else {
    regexStr = pattern.toString();
    regex = pattern;
  }
    
  return regex;
}

// Consider your string inputs:
let re1 = buildPattern("^\d{4}-\d{2}-\d{2}$")
// output: /^^d{4}-d{2}-d{2}$$/

let re2 = buildPattern("\d{4}-\d{2}-\d{2}")
// output: /^d{4}-d{2}-d{2}$/

let re3 = buildPattern("/^\d{4}-\d{2}-\d{2}$/")
// output: /^\/^d{4}-d{2}-d{2}$\/$/

re1.test("1234-24-23")
// false

re2.test("1234-24-23")
// false

re3.test("1234-24-23")
// false

Let’s now consider re2

// input
"\d{4}-\d{2}-\d{2}"

// output
/^d{4}-d{2}-d{2}$/

Notice all backslashes gone \. That’s because how RegExp constructor works - you need to escape some symbols. (details: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Description)

So this works.

buildPattern("\\d{4}-\\d{2}-\\d{2}").test("1234-24-23")

I suggest you to just always use regular expression instead of string and do not do extra work escaping pattern. I hope all is clear now.

PS: also with regular expression you can set any regex flags you want + do not limit you with ^$ if you don’t need them.

Have you tried to use \\. insted of \. in your string pattern?

@DzmitryShylovich , hi, I’ve run into some strange behavior of pattern validator, but don’t know if it’s deserved own issue. I need to validate field if it has at least on caps letter and one number, so I’ve used pattern validator with this regexp /^(?=.*[A-Z])(?=.*\d).*$/g. It validates field very weird if I type an even number of symbols it validates correctly (for example Q1, Q1as and so on), but an odd number of symbols always give me an invalid state of the field (Q1a, Q1as3, …). I’ve provided an example on plunker: https://plnkr.co/edit/TaVfZ6bk5mY9kKj64sKb?p=preview But, if I remove g flag from regular expression it works as expected. Please, take a look, is it an issue of the pattern validator or I just wrote incorrect regexp? Thank you 😄

@tytskyi your suggestion works perfectly… Whats the difference? in what cases I should use that insted of a string?

I’m sorry but we can’t reproduce the problem following the instructions you provided.

If the problem still exists please open a new issue following our submission guidelines.