苦苦挣扎的正则表达式代码:CamelCase到camel_case

时间:2014-01-11 14:53:01

标签: c# regex

我能够使用正则表达式将字符串MyClassName转换为my_class_name

但是,我的解决方案无法与MyOtherTClassName一起使用,应该转换为my_other_t_class_name

此外,这也不适用于ClassNumber1,应转换为class_number_1

没有进入我的解决方案,这还不够好,我想帮助改进的正则表达式代码:

  1. MyClassName - > my_class_name
  2. MyOtherTClassName - > my_other_t_class_name
  3. MyClassWith1Number - > my_class_with_1_number
  4. 谢谢,

2 个答案:

答案 0 :(得分:4)

背后的逻辑是,您希望将每个大写字母转换为小写字母,并在其前面(和每个数字)用下划线。
例如,T变为_t6变为_6 唯一的例外是第一个角色。你不希望在它之前加上一个下层。正则表达式将使用negative lookbehind处理此情况,以便与第一个字符不匹配。

//using System.Text.RegularExpression

//your input
string input = "MyOtherTClass1Name";

//the regex
string result = Regex.Replace(
    input, 
    "((?<!^)[A-Z0-9])", //the regex, see below for explanation
    delegate(Match m) { return "_" + m.ToString().ToLower(); }, //replace function
    RegexOptions.None
);
result = result.ToLower(); //one more time ToLower(); for the first character of the input

Console.WriteLine(result);

对于正则表达式本身:

(           #start of capturing group
  (?<!      #negative lookbehind
     ^      #beginning of the string
  )         #end of lookbehind
  [A-Z0-9]  #one of A-Z or 0-9
)           #end of capturing group

因此,我们捕获每个大写字母和每个数字(第一个字符除外),并用自己的小写变体和前面的下划线替换它们。

答案 1 :(得分:0)

我最近遇到了这个问题,如果只有一个数字,但前面的答案有效,但如果有两个或更多连续数字,则每个数字都会在它们之前有一个下划线。我用它在PHP中为我转换它。

strtolower(preg_replace('/(?<!^)([A-Z])|(?<![0-9])([0-9])/', '_$1$2', $string))

我相信正则表达式应该和C#一样,所以我会打破它。

(?<!       # negative look behind
   ^       # beginning of string
)
([A-Z])    # one of capital letters
|          # or
(?<!       # negative look behind
   [0-9]   # one of digits
)
([0-9])    # one of digits

字母的想法是一样的。确保它不是字符串的开头。对于数字,只需确保前一个字符也不是数字。我们不必担心它是字符串的开头,因为字符串不会以数字开头。