Slava
Slava

Reputation: 6640

Regex for ClassName.PropertyName

I don't know Regex,

But I need to have regex expression for evaluation of ClassName.PropertyName?

Need to validate some values from appSettings for being compliant with ClassName.PropertyName convention

"ClassName.PropertyName" - this is the only format that is valid, the rest below is invalid:

"Personnel.FirstName1"   <- the only string that should match
"2Personnel.FirstName1"
"Personnel.33FirstName"
"Personnel..FirstName"
"Personnel.;FirstName"
"Personnel.FirstName."
"Personnel.FirstName   "
" Personnel.FirstName"
" Personnel. FirstName"
" 23Personnel.3FirstName"

I have tried this (from the link posted as duplicate):

 ^\w+(.\w+)*$

but it doesn't work: I have false positives, e.g. 2Personnel.FirstName1 as well as Personnel.33FirstName passes the check when both should have been rejected.

Can someone help me with that?

Upvotes: 2

Views: 1484

Answers (2)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

Let's start from single identifier:

  1. Its first character must be letter or underscope
  2. It can contain letters, underscopes and digits

So the regular expression for an identifier is

[A-Za-z_][A-Za-z0-9_]*

Next, we should chain identifier with . (do not forget to escape .) an indentifier followed by zero or more . + identifier:

^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$

In case it must be exactly two identifiers (and not, say abc.def.hi - three ones)

^[A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_]*$

Tests:

string[] tests = new string[] {
  "Personnel.FirstName1",  // the only string that should be matched
  "2Personnel.FirstName1",
  "Personnel.33FirstName",
  "Personnel..FirstName",
  "Personnel.;FirstName",
  "Personnel.FirstName.",
  "Personnel.FirstName   ",
  " Personnel.FirstName",
  " Personnel. FirstName",
  " 23Personnel.3FirstName",
} ;

string pattern = @"^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$";

var results = tests
  .Select(test => 
    $"{"\"" + test + "\"",-25} : {(Regex.IsMatch(test, pattern) ? "matched" : "failed")}"");

Console.WriteLine(String.Join(Environment.NewLine, results));

Outcome:

"Personnel.FirstName1"    : matched
"2Personnel.FirstName1"   : failed
"Personnel.33FirstName"   : failed
"Personnel..FirstName"    : failed
"Personnel.;FirstName"    : failed
"Personnel.FirstName."    : failed
"Personnel.FirstName   "  : failed
" Personnel.FirstName"    : failed
" Personnel. FirstName"   : failed
" 23Personnel.3FirstName" : failed

Edit: In case culture specific names (like äöü.FirstName) should be accepted (see Rand Random's comments) then [A-Za-z] range should be changed into \p{L} - any letter. Exotic possibility - culture specific digits (e.g. Persian ones - ۰۱۲۳۴۵۶۷۸۹) can be solved by changing 0-9 into \d

// culture specific letters, but not digits 
string pattern = @"^[\p{L}_][\p{L}0-9_]*(?:\.[\p{L}_][\p{L}0-9_]*)*$";

If each identifier should not exceed sertain length (say, 16) we should redesign initial identifier pattern: mandatory letter or underscope followed by [0..16-1] == {0,15} letters, digits or underscopes

[A-Za-z_][A-Za-z0-9_]{0,15}

And we have

string pattern = @"^[A-Za-z_][A-Za-z0-9_]{0,15}(?:\.[A-Za-z_][A-Za-z0-9_]{0,15})*$";

Upvotes: 5

Ares
Ares

Reputation: 1366

^[A-Za-z]*\.[A-Za-z]*[0-9]$

or

^[A-Za-z]*\.[A-Za-z]*[0-9]+$

if you need more than one numerical character in the number suffix

Upvotes: 0

Related Questions