Validations.pattern doesn't work with Regex

2020-04-17 04:02发布

问题:

I have reactive form and one of the controls should be validated with the pattern .*[^\s].*. In case it is used in template-driven forms, it works well. But in a case of reactive - does not. What should I change to fix it?

this._form = this._formBuilder.group({
  description: ['', [Validators.required, Validators.pattern('.*[^\S].*')]]
}

回答1:

Have a look at the Validator.js:

/**
* Validator that requires a control to match a regex to its value.
*/
static pattern(pattern: string|RegExp): ValidatorFn {
    if (!pattern) return Validators.nullValidator;
    let regex: RegExp;
    let regexStr: string;
    if (typeof pattern === 'string') {
      regexStr = `^${pattern}$`;
      regex = new RegExp(regexStr);
    } else {
      regexStr = pattern.toString();
      regex = pattern;
    }
    return (control: AbstractControl): {[key: string]: any} => {
      if (isEmptyInputValue(control.value)) {
        return null;  // don't validate empty values to allow optional controls
      }
      const value: string = control.value;
      return regex.test(value) ? null :
                                 {'pattern': {'requiredPattern': regexStr, 'actualValue': value}};
    };
  }

The point is that the regex pattern is passed either like a regex literal, or as a string literal. When you pass it as a regex literal, you may use

/\S*\s.*/

It will be "converted" to a string with pattern.toString() and ^ and $ will be added - "^\\S*\\s.*$". This is exactly a string pattern you may pass in the Validators.Pattern, too.

Note that ^\S*\s.*$ will match a string that starts with 0+ non-whitespace chars, then has 1 obligatory whitespace, and then has any 0+ chars other than line break chars. It is a bit faster than /^.*\s.*$/. Note that \s = [^\S].