0

I'm trying to evaluate a string against a set list of parameters with RegExp in Flutter. For example, the string must contain at least:

  • One capital letter
  • One lowercase letter
  • One number from 0-9
  • One special character, such as $ or !

This is basically for a password entry field of an application. I have set things up, firstly using validateStructure as follows:

abstract class PasswordValidator {
  bool validateStructure(String value);
}

Then, I have used the RegExp function as follows:

class PasswordValidatorSpecial implements PasswordValidator {
  bool validateStructure(String value) {
    String pattern =
        r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~£]).{8,}$';
    RegExp regEx = new RegExp(pattern);
    return regEx.hasMatch(value);
  }
}

This does work well, in a sense that when I pass a string/password through it, it does tell me if at least one of the criteria is not met. However, what I would like to do is for the output to be more specific, telling me which of those criteria isn't met.

For example, if the password were to have everything but a number (from 0-9) I would want to be able to get the output to specifically say that a number is missing, but everything else is present.

How would I adapt my code to be able to do that? I thought perhaps by using conditional 'if' statement, although I don't know how that would work. Thanks!

1 Answer 1

1

That's right, you can use RegExr to check your RegExp, separate each part and use them separately to have a custom error. Also instead of return a bool value, you can return a String value, such as the following function:

String validateStructure(String value) {
    String patternUpperCaseCharacters = r'^(?=.*?[A-Z])';
    String patternLowerCaseCharacters = r'^(?=.*?[a-z])';
    String patternNumbers = r'^(?=.*?[0-9])';
    String patternSpecialCharacters = r'^(?=.*?[!@#\$&*~£])';

    RegExp regEx = new RegExp(patternUpperCaseCharacters);
    if (regEx.hasMatch(value)) {
      regEx = new RegExp(patternLowerCaseCharacters);
      if (regEx.hasMatch(value)) {
        return "More errors";
      } else {
        return "You need at least one lowercase letter";
      }
    } else {
      return "You need at least one capital letter";
    }
  }
Sign up to request clarification or add additional context in comments.

3 Comments

I actually really like that, thanks! It is quite easy to understand, when it shows the errors sequentially, so it doesn't just show them all at once. The email form I have created uses TextField() with a decoration field, that has errorText as a parameter. To allow the output string of the validateStructure function to be called here (to be shown under the cell), would I simply write errorText: validateStructure? Or is there a better way of doing it?
There are many ways to do that, personally I like to use Streams and setState for form validations, I imagine that you are using the second one, so you can call the validateStructure function in the onChanged parameter of your TextField, and update the state in the corresponding place. And to use the Streams please check the point 4 of Form Validations in this article: didierboelens.com/2018/12/…
Thanks for the advice and the link. I appreciate it. I'll give it a go today and see how far I get.

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.