如何将驼峰案例标识符与正则表达式匹配?

时间:2018-09-08 11:20:47

标签: c# regex camelcasing

我需要匹配驼峰大小写变量。我忽略了名称中带有数字的变量。

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)+”在线匹配,因此请勿从那里进行测试并进行验证。

似乎在进行更改时我的部署未获得更新,因此可能根本没有问题。

以下内容几乎可以解决线路起始问题。注意,我注意到我不需要后缀部分,因为匹配以[a-z]内容结尾。

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]+)+";

2 个答案:

答案 0 :(得分:1)

今天遇到了同样的问题,什么对我有用:

\b([a-z][a-z0-9]+[A-Z])+[a-z0-9]+\b

注意:这是针对PCRE正则表达式的

说明:

`(` group begin

`[a-z]` start with a lower-case letter

`[a-z0-9]+` match a string of all lowercase/numbers

`[A-Z]` an upper-case letter

`)+` group end; match one or more of such groups.

以更多小写字母/数字结尾。 \b表示单词边界。

在我的情况下,_camelCaseIdent_s在单词之间仅高出一个字母。 因此,这对我有用,但是如果您可以(或想要匹配)多个 介于两者之间的大写字母,您可以执行类似[A-Z]{1,2}

的操作

答案 1 :(得分:0)

您可以在前缀和后缀之间匹配一个空位置,以分割驼峰标识符

(?<=[_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