Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex - PascalCase to lower case with underscores

Tags:

c#

regex

I'm trying to convert PascalCase property names such as Is24Hour, Is512 to JSON-style lowercase with underscores (ie. is_24_hour, is_512) using C#.

So far I've got far but it doesn't work for multiple numbers.

([A-Z])([A-Z0-9][a-z])|([a-z0-9])([A-Z0-9])

With the replacement expression ($1$3_$2$4)

For example "Is24Hour" becomes "Is_24_Hour" (which is then lower-cased by .ToLower()). but "Is512" becomes "Is_51_2".

like image 380
Jamie Avatar asked Jan 06 '14 14:01

Jamie


2 Answers

Use String.ToLower for the lowercase.

For the regex, the following seems to work:

((?<=.)[A-Z][a-zA-Z]*)|((?<=[a-zA-Z])\d+)

combined with the replacement expression:

_$1$2

Here's a full sample:

string strRegex = @"((?<=.)[A-Z][a-zA-Z]*)|((?<=[a-zA-Z])\d+)";
Regex myRegex = new Regex(strRegex, RegexOptions.Multiline);
string strTargetString = @"Is24Hour" + "\n" + 
    @"Is512" + "\n" + @"A12Hour4" + "\n" + 
    @"23AHourDay12" + "\n" + @"An8DAY512";

string strReplace = @"_$1$2";

return myRegex.Replace(strTargetString, strReplace).ToLower();
like image 164
Alex Filipovici Avatar answered Sep 28 '22 13:09

Alex Filipovici


The accepted solution does not work for strings like "23AHourDay12", it produces "23_ahourday_12", but should "23_a_hour_day_12" (see the @vaindil comment)

Here is a solution using Linq, instead of Regex:

public static class ExtensionMethods {
    public static string ToUnderscoreCase(this string str) {
        return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower();
    }
}

Thanks @vkobel github user. Source: https://gist.github.com/vkobel/d7302c0076c64c95ef4b

like image 27
Konstantin Gindemit Avatar answered Sep 28 '22 12:09

Konstantin Gindemit