20

I need to validate a form that a user provides their name and a number. I have a regex that is supposed to make sure the name contains only letters and nothing else and also for the number input i need to make sure only numbers are in the field. The code I have looks like

 validator: (value) => value.isEmpty
                        ? 'Enter Your Name'
                        : RegExp(
                                '!@#<>?":_``~;[]\|=-+)(*&^%1234567890')
                            ? 'Enter a Valid Name'
                            : null,

can i get a regex expression that validates a name in such a way if any special character or number is inputted it becomes wrong meaning only letters are valid and another that validates a number in such a way if an alphabetical letter or any special character is inputted it becomes wrong meaning only the input of a number is valid

Taio
  • 3,152
  • 11
  • 35
  • 59
  • Looks like you wanted `RegExp(r'[!@#<>?":_\`~;[\]\\|=+)(*&^%0-9-]').hasMatch(value)`. You need to use a raw string literal, put `-` at the end and escape `]` and ``\`` chars, then check if there is a match with `.hasMatch(value)`. `[0123456789]` = `[0-9]`. – Wiktor Stribiżew Aug 24 '18 at 21:12
  • This works for the Name RegExp. Can you explain for the number one. In this one, the user is presented with the number keyboard so some characters are not important as such. I have just copied the name Regex and pasted it here but removed `0-9` in order to be able to input the numbers. Problem is, when a space is inserted, it still counts it as a value. How can i correct this. – Taio Aug 25 '18 at 08:14
  • Add `\s` - `r'[!@#<>?":_\`~;[\]\\|=+)(*&^%\s-]'` – Wiktor Stribiżew Aug 25 '18 at 09:11
  • Yes. This works. You can add the answer – Taio Aug 25 '18 at 09:32

5 Answers5

24

Create a static final field for the RegExp to avoid creating a new instance every time a value is checked. Creating a RegExp is expensive.

static final RegExp nameRegExp = RegExp('[a-zA-Z]'); 
    // or RegExp(r'\p{L}'); // see https://stackoverflow.com/questions/3617797/regex-to-match-only-letters 
static final RegExp numberRegExp = RegExp(r'\d');

Then use it like

validator: (value) => value.isEmpty 
    ? 'Enter Your Name'
    : (nameRegExp.hasMatch(value) 
        ? null 
        : 'Enter a Valid Name');
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    Both are not working. In the question I specified I need something that will not accept anything else other than alphabetical letters, for the name. And for the number input, numbers only not a special character or anything else. This regex thing is awfully stressful – Taio Aug 24 '18 at 17:32
  • eg. for the name if it is **gunter zochbauer** if a comma is present somewhere it becomes wrong – Taio Aug 24 '18 at 17:35
  • You demanded "only letters". Did you check the commented out alternative. If this us not what you want please formulate your question more precise. – Günter Zöchbauer Aug 24 '18 at 17:50
  • i have edited the original question to further explain it. Apologies – Taio Aug 24 '18 at 18:08
  • I still don't think it is unclear how my answer does not answer your question. `RegExp('[a-zA-Z\ ]')` validates to `true` for my name. – Günter Zöchbauer Aug 24 '18 at 20:12
17

It seems to me you want

RegExp(r'[!@#<>?":_`~;[\]\\|=+)(*&^%0-9-]').hasMatch(value)

Note that you need to use a raw string literal, put - at the end and escape ] and \ chars inside the resulting character class, then check if there is a match with .hasMatch(value). Notre also that [0123456789] is equal to [0-9].

As for the second pattern, you can remove the digit range from the regex (as you need to allow it) and add a \s pattern (\s matches any whitespace char) to disallow whitespace in the input:

RegExp(r'[!@#<>?":_`~;[\]\\|=+)(*&^%\s-]').hasMatch(value)
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Some people combine their last names after marriage, making their names include a hyphen. Do you know how to make a hyphen/dash ( - ) an exception? – Texv Jun 11 '22 at 07:24
  • Do not forget to add / into the RegExp(r'[!@#<>?"/·:_`~;[\]\\|=+)(*&^%0-9-]') – PatricioS Aug 11 '22 at 20:07
8

Base on this answer and this information:

\p{L} or \p{Letter}: any kind of letter from any language.

Reference: http://www.regular-expressions.info/unicode.html

The regex for a name validation:

RegExp(r"^[\p{L} ,.'-]*$",
      caseSensitive: false, unicode: true, dotAll: true)
  .hasMatch(my_name)
Duan Nguyen
  • 468
  • 5
  • 10
3

this worked for me

void main() {
  RegExp nameRegex = RegExp(r"^[a-zA-Z]+$");
  RegExp numberRegex = RegExp(r"^\d+$");
  print(nameRegex.hasMatch("Ggggg"));
  print(numberRegex.hasMatch("999"));
}
0

The following code should also work.
The parser is a constant expression, it is fast and does not consume much memory.

import 'package:parser_combinator/parser/alpha1.dart';
import 'package:parser_combinator/parser/digit1.dart';
import 'package:parser_combinator/parser/eof.dart';
import 'package:parser_combinator/parser/many1.dart';
import 'package:parser_combinator/parser/predicate.dart';
import 'package:parser_combinator/parser/skip_while.dart';
import 'package:parser_combinator/parser/terminated.dart';
import 'package:parser_combinator/parsing.dart';

void main(List<String> args) {
  const name = Terminated(
    Many1(
      Terminated(Alpha1(), SkipWhile(isWhitespace)),
    ),
    Eof(),
  );

  const number = Terminated(Digit1(), Eof());

  final input1 = 'John  Snow '.trim();
  final r1 = tryParse(name.parse, input1).result;
  if (r1 != null) {
    final fullName = r1.value;
    print('Name is valid: $input1');
    print('First name: ${fullName.first}');
    if (fullName.length > 1) {
      print('Second name: ${fullName[1]}');
    }
  }

  final input2 = ' 123 '.trim();
  final r2 = tryParse(number.parse, input2).result;
  if (r2 != null) {
    print('Number is valid: $input2');
  }
}

Output:

Name is valid: John  Snow
First name: John
Second name: Snow
Number is valid: 123
mezoni
  • 10,684
  • 4
  • 32
  • 54