首页 > 解决方案 > 如何使用正则表达式匹配骆驼大小写标识符?

问题描述

我需要匹配骆驼案例变量。我忽略了名称中带有数字的变量。

private const String characters = @"\-:;*+=\[\{\(\/?\s^""'\<\]\}\.\)$\>";
private const String start = @"(?<=[" + characters +"])[_a-z]+";
private const String capsWord = "[_A-Z]{1}[_a-z]+";
private const String end = @"(?=[" + characters + "])";

var regex =  new Regex($"{start}{capsWord}{end}", 
    RegexOptions.Compiled | RegexOptions.CultureInvariant) }

这非常适合匹配单个驼峰变量!但不是多个,也不是满足行尾的那个。我认为我的角色中的 $ 或 ^ 会允许它们匹配。

abcDef                                     // match 
notToday<end of line>                      // no match
<start of line>intheBeginning              // no match
whatIf                                     // match
"howFar"                                   // match
(whatsNext)                                // match
ohMyGod                                    // two humps don't match

我也试过像这样“(capsWord)+”包装我的capsWord,但它也不起作用。警告!正则表达式测试器使用此“(capsWord)+”进行在线匹配,因此不要从那里通过测试来验证和响应。

当我进行更改时,我的部署似乎没有得到更新,所以毕竟可能没有问题。

除了行首问题之外,以下几乎可以工作。请注意,我注意到我不需要后缀部分,因为匹配以 [az] 内容结尾。

private const String characters = @"\-:;*+=\[\{\(\/?\s^""'\<\]\}\.\)$\>";
private const String pattern = "(?<=[" + characters + "])[_a-z]+([A-Z][a-z]+)+";

abcDef                                     // match 
notToday<end of line>                      // match
<start of line>intheBeginning              // no match
whatIf                                     // match
"howFar"                                   // match
(whatsNext)                                // match
ohMyGod                                    // match

所以,如果有人能解决它,请告诉我。

我还将其他字符简化为更简洁的表达式,但从行首开始匹配仍然存在问题。

private const String pattern = "(?<=[^a-zA-Z])[_a-z]+([A-Z][a-z]+)+";

标签: c#regexcamelcasing

解决方案


您可以匹配前缀和后缀之间的空位置来拆分驼峰式标识符

(?<=[_a-z])(?=[_A-Z])

前缀包含小写字母,后缀包含大写字母。


如果要匹配 camelCase 标识符,可以使用

(?<=^|[^_a-zA-Z])_*[a-z]+[_a-zA-Z]*

这个怎么运作:

(?<=                Match any position pos following a prefix exp    (?<=exp)pos
    ^               Beginning of line
    |               OR
    [^_a-zA-Z]      Not an identifier character
)
_*                  Any number of underlines
[a-z]+              At least one lower case letter
[_a-zA-Z]*          Any number of underlines and lower or upper case letters

所以,它基本上说:匹配一个序列,可选地以下划线开头,后跟至少一个小写字母,可选地后跟下划线和字母(大写和小写),并且整个内容必须以行首或开头非标识符字符。这对于确保我们不仅匹配以大写字母(或下划线和大写字母)开头的标识符的结尾是必要的。

var camelCaseExpr = new Regex("(?<=^|[^_a-zA-Z])_*[a-z]+[_a-zA-Z]*");
MatchCollection matches = camelCaseExpr.Matches("whatIf _Abc _abc howFar");
foreach (Match m in matches) {
    Console.WriteLine(m.Value);
}

印刷

whatIf
_abc
howFar

推荐阅读