首页 > 解决方案 > ClassName.PropertyName 的正则表达式

问题描述

我不知道Regex

但我需要有正则表达式来评估ClassName.PropertyName

需要验证 appSettings 中的某些值是否符合ClassName.PropertyName约定

“ClassName.PropertyName” - 这是唯一有效的格式,下面的其余格式无效:

"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"

我已经尝试过了(来自发布为重复的链接):

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

但它不起作用:我有误报,例如2Personnel.FirstName1,当两者都应该被拒绝时,我也Personnel.33FirstName 通过了检查

有人可以帮我吗?

标签: c#regex

解决方案


让我们从单个标识符开始:

  1. 它的第一个字符必须是字母或下划线
  2. 它可以包含字母、下划线和数字

所以标识符的正则表达式是

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

接下来,我们应该将标识符与.(不要忘记转义.)一个标识符链接起来,后跟零个或多个.+ 标识符:

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

如果它必须恰好是两个标识符(而不是,比如说abc.def.hi- 三个)

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

测试:

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));

结果:

"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

编辑:如果应该接受文化特定名称(如)(请参阅 Rand Random 的评论),则范围应更改为-任何字母。异国情调的可能性 - 文化特定的数字(例如波斯数字 - )可以通过更改为来解决äöü.FirstName[A-Za-z]\p{L}۰۱۲۳۴۵۶۷۸۹0-9\d

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

如果每个标识符不应该超过一定的长度(比如,16),我们应该重新设计初始标识符模式:强制字母或下划线后跟[0..16-1] == {0,15}字母、数字或下划线

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

我们有

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

推荐阅读