I want to include some special characters in a string variable name in C#.
Example:
string foo-bar = String.Empty;
As far as my understand I can't declare a variable as I mentioned in the above example.
Is there any way around to declare a variable name with "-" included?
From MSDN:
You can't just choose any sequence of characters as a variable name. This isn't as worrying as it might sound, however, because you're still left with a very flexible naming
system.
The basic variable naming rules are as follows:
The first character of a variable name must be either a letter, an underscore character (_), or the at symbol (#).
Subsequent characters may be letters, underscore characters, or numbers.
No, this is not possible to do in C#.
If you really, really, really want to so this, you could use a Dictionary<string, string>:
Dictionary<string, string> someVars = new Dictionary<string, string>()
{
{"foo-bar", String.Empty},
{"bar-foo", "bazinga"}
}
Using them would look like this:
string newstring = someVars["foo-bar"] + "Hello World!";
Instead of just using the variable name, you would look up the string in your dictionary. Note that this is very inefficient and just intended as a joke, so please do no really use this ;)
If you are trying to deserialize object, you can use JsonProperty to acieve this.
Example:
public class SubscriptionListJsonData
{
[JsonProperty(PropertyName = "subscriptions")]
public string SubscriptionData { get; set; }
[JsonProperty(PropertyName = "#nextLink")]
public string nextLink { get; set; }
}
Follow this link for partially reading Json.
You can't do that in c# and most of other programming languages .. I also advice you to follow the C# naming conventions as it help you read your code in a way that -at least for me- always felt comfortable .
Related
a bit of an unusual one.. but I was wondering if anyone knew how I could declare a reserved word as a variable. I have the following code, but it does not like my use of the long variable name. I know I could rename it, but for instrest sakes I would like to know if this is at all possible.
private string lat;
private string long;
public string Lat
{
get
{
return lat;
}
}
public string Long
{
get
{
return long;
}
}
Yes, you can if you really want to:
private string #long;
The actual name of the variable (as reported by reflection etc) is just long; the # sign tells the compiler to ignore the fact that it's also a keyword.
I would very strongly advise against this, however.
As others have mentioned, you can escape a reserved word with #.
In your example you don't really need to, I would write the property like this:
private string _long;
public string Long
{
get
{
return _long;
}
}
And the underscore and the capital L make it compile.
But it's kind of a tradition to call them Lat and Lon, or even better: Latitude and Longitude.
Yes, you can. Using the # symbol.
This will work, for example: private string #long;
Doing this is highly not recommended, but it is possible.
Not an answer I know as I would steer clear of using reserved words as variable names, but if you insist then at least use the following:
private string lat;
private string #long;
public string Lat
{
get
{
return this.lat;
}
}
public string Long
{
get
{
return this.long;
}
}
I may be late to this party, but I thought I would throw in another place where using a reserved word as a variable name is a good idea!!
I am writing a web control, where I want one of the properties to be "class" in a similar manner as other elements have a "class" property.
So, indeed I will make my property be: "public string #class {get{} set{}}"
C#6.0 have a string interpolation - a nice feature to format strings like:
var name = "John";
WriteLine($"My name is {name}");
The example is converted to
var name = "John";
WriteLine(String.Format("My name is {0}", name));
From the localization point of view, it is much better to store strings like :
"My name is {name} {middlename} {surname}"
than in String.Format notation:
"My name is {0} {1} {2}"
How to use the string interpolation for .NET localization? Is there going to be a way to put $"..." to resource files? Or should strings be stored like "...{name}" and somehow interpolated on fly?
P.S. This question is NOT about "how to make string.FormatIt extension" (there are A LOT of such libraries, SO answers, etc.). This question is about something like Roslyn extension for "string interpolation" in "localization" context (both are terms in MS .NET vocabulary), or dynamic usage like Dylan proposed.
An interpolated string evaluates the block between the curly braces as a C# expression (e.g. {expression}, {1 + 1}, {person.FirstName}).
This means that the expressions in an interpolated string must reference names in the current context.
For example this statement will not compile:
var nameFormat = $"My name is {name}"; // Cannot use *name*
// before it is declared
var name = "Fred";
WriteLine(nameFormat);
Similarly:
class Program
{
const string interpolated = $"{firstName}"; // Name *firstName* does not exist
// in the current context
static void Main(string[] args)
{
var firstName = "fred";
Console.WriteLine(interpolated);
Console.ReadKey();
}
}
To answer your question:
There is no current mechanism provided by the framework to evaluate interpolated strings at runtime. Therefore, you cannot store strings and interpolate on the fly out of the box.
There are libraries that exist that handle runtime interpolation of strings.
According to this discussion on the Roslyn codeplex site, string interpolation will likely not be compatible with resource files (emphasis mine):
String interpolation could be neater and easier to debug than either String.Format or concatenation...
Dim y = $"Robot {name} reporting
{coolant.name} levels are {coolant.level}
{reactor.name} levels are {reactor.level}"
However, this example is fishy. Most professional programmers won't be writing
user-facing strings in code. Instead they'll be storing those strings in resources (.resw, .resx or .xlf) for reasons of localization. So there doesn't seem much use for string interpolation here.
Assuming that your question is more about how to localise interpolated strings in your source code, and not how to handle interpolated string resources...
Given the example code:
var name = "John";
var middlename = "W";
var surname = "Bloggs";
var text = $"My name is {name} {middlename} {surname}";
Console.WriteLine(text);
The output is obviously:
My name is John W Bloggs
Now change the text assignment to fetch a translation instead:
var text = Translate($"My name is {name} {middlename} {surname}");
Translate is implemented like this:
public static string Translate(FormattableString text)
{
return string.Format(GetTranslation(text.Format),
text.GetArguments());
}
private static string GetTranslation(string text)
{
return text; // actually use gettext or whatever
}
You need to provide your own implementation of GetTranslation; it will receive a string like "My name is {0} {1} {2}" and should use GetText or resources or similar to locate and return a suitable translation for this, or just return the original parameter to skip translation.
You will still need to document for your translators what the parameter numbers mean; the text used in the original code string doesn't exist at runtime.
If, for example, in this case GetTranslation returned "{2}. {0} {2}, {1}. Don't wear it out." (hey, localisation is not just about language!) then the output of the full program would be:
Bloggs. John Bloggs, W. Don't wear it out.
Having said this, while using this style of translation is easy to develop, it's hard to actually translate, since the strings are buried in the code and only surface at runtime. Unless you have a tool that can statically explore your code and extract all the translatable strings (without having to hit that code path at runtime), you're better off using more traditional resx files, since they inherently give you a table of text to be translated.
As already said in previous answers: you currently cannot load the format string at runtime (e.g. from resource files) for string interpolation because it is used at compile time.
If you don't care about the compile time feature and just want to have named placeholders, you could use something like this extension method:
public static string StringFormat(this string input, Dictionary<string, object> elements)
{
int i = 0;
var values = new object[elements.Count];
foreach (var elem in elements)
{
input = Regex.Replace(input, "{" + Regex.Escape(elem.Key) + "(?<format>[^}]+)?}", "{" + i + "${format}}");
values[i++] = elem.Value;
}
return string.Format(input, values);
}
Be aware that you cannot have inline expressions like {i+1} here and that this is not code with best performance.
You can use this with a dictionary you load from resource files or inline like this:
var txt = "Hello {name} on {day:yyyy-MM-dd}!".StringFormat(new Dictionary<string, object>
{
["name"] = "Joe",
["day"] = DateTime.Now,
});
String interpolation is difficult to combine with localization because the compiler prefers to translate it to string.Format(...), which does not support localization. However, there is a trick that makes it possible to combine localization and string interpolation; it is described near the end of this article.
Normally string interpolation is translated to string.Format, whose behavior cannot be customized. However, in much the same way as lambda methods sometimes become expression trees, the compiler will switch from string.Format to FormattableStringFactory.Create (a .NET 4.6 method) if the target method accepts a System.FormattableString object.
The problem is, the compiler prefers to call string.Format if possible, so if there were an overload of Localized() that accepted FormattableString, it would not work with string interpolation because the C# compiler would simply ignore it [because there is an overload that accepts a plain string]. Actually, it's worse than that: the compiler also refuses to use FormattableString when calling an extension method.
It can work if you use a non-extension method. For example:
static class Loca
{
public static string lize(this FormattableString message)
{ return message.Format.Localized(message.GetArguments()); }
}
Then you can use it like this:
public class Program
{
public static void Main(string[] args)
{
Localize.UseResourceManager(Resources.ResourceManager);
var name = "Dave";
Console.WriteLine(Loca.lize($"Hello, {name}"));
}
}
It's important to realize that the compiler converts the $"..." string into an old-fashioned format string. So in this example, Loca.lize actually receives "Hello, {0}" as the format string, not "Hello, {name}".
Using the Microsoft.CodeAnalysis.CSharp.Scripting package you can achieve this.
You will need to create an object to store the data in, below a dynamic object is used. You could also create an specific class with all the properties required. The reason to wrap the dynamic object in a class in described here.
public class DynamicData
{
public dynamic Data { get; } = new ExpandoObject();
}
You can then use it as shown below.
var options = ScriptOptions.Default
.AddReferences(
typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).GetTypeInfo().Assembly,
typeof(System.Runtime.CompilerServices.DynamicAttribute).GetTypeInfo().Assembly);
var globals = new DynamicData();
globals.Data.Name = "John";
globals.Data.MiddleName = "James";
globals.Data.Surname = "Jamison";
var text = "My name is {Data.Name} {Data.MiddleName} {Data.Surname}";
var result = await CSharpScript.EvaluateAsync<string>($"$\"{text}\"", options, globals);
This is compiling the snippet of code and executing it, so it is true C# string interpolation. Though you will have to take into account the performance of this as it is actually compiling and executing your code at runtime. To get around this performance hit if you could use CSharpScript.Create to compile and cache the code.
The C# 6.0 string interpolation won't help you if the format string is not in your C# source code. In that case, you will have to use some other solution, like this library.
If we use interpolation then we are thinking in terms of methods, not constants. In that case we could define our translations as methods:
public abstract class InterpolatedText
{
public abstract string GreetingWithName(string firstName, string lastName);
}
public class InterpolatedTextEnglish : InterpolatedText
{
public override string GreetingWithName(string firstName, string lastName) =>
$"Hello, my name is {firstName} {lastName}.";
}
We can then load an implementation of InterpolatedText for a specific culture. This also provides a way to implement fallback, as one implementation can inherit from another. If English is the default language and other implementations inherit from it, there will at least be something to display until a translation is provided.
This seems a bit unorthodox, but offers some benefits:
Primarily, the string used for interpolation is always stored in a strongly-typed method with clearly-specified arguments.
Given this: "Hello, my name is {0} {1}" can we determine that the placeholders represent first name and last name in that order? There will always be a method which matches values to placeholders, but there's less room for confusion when the interpolated string is stored with its arguments.
Similarly, if we store our translation strings in one place and use them in another, it becomes possible to modify them in a way that breaks the code using them. We can add {2} to a string which will be used elsewhere, and that code will fail at runtime.
Using string interpolation this is impossible. If our translation string doesn't match the available arguments it won't even compile.
There are drawbacks, although I see difficulty in maintaining any solution.
The greatest is portability. If your translation is coded in C# and you switch, it's not the easiest thing to export all of your translations.
It also means that if you wish to farm out translations to different individuals (unless you have one person who speaks everything) then the translators must modify code. It's easy code, but code nonetheless.
Interpolated strings can not refactored out from their (variable) scope because of using of the embedded variables in them.
The only way to relocate the string literal part is passing the scope bound variables as parameter to an other location, and mark their position in the string with special placeholders. However this solution is already "invented" and out there:
string.Format("literal with placeholers", parameters);
or some of advanced library (interpolating runtime), but using the very same concept (passing parameters).
Then you can refactor out the "literal with placeholers" to a resource.
C#6.0 have a string interpolation - a nice feature to format strings like:
var name = "John";
WriteLine($"My name is {name}");
The example is converted to
var name = "John";
WriteLine(String.Format("My name is {0}", name));
From the localization point of view, it is much better to store strings like :
"My name is {name} {middlename} {surname}"
than in String.Format notation:
"My name is {0} {1} {2}"
How to use the string interpolation for .NET localization? Is there going to be a way to put $"..." to resource files? Or should strings be stored like "...{name}" and somehow interpolated on fly?
P.S. This question is NOT about "how to make string.FormatIt extension" (there are A LOT of such libraries, SO answers, etc.). This question is about something like Roslyn extension for "string interpolation" in "localization" context (both are terms in MS .NET vocabulary), or dynamic usage like Dylan proposed.
An interpolated string evaluates the block between the curly braces as a C# expression (e.g. {expression}, {1 + 1}, {person.FirstName}).
This means that the expressions in an interpolated string must reference names in the current context.
For example this statement will not compile:
var nameFormat = $"My name is {name}"; // Cannot use *name*
// before it is declared
var name = "Fred";
WriteLine(nameFormat);
Similarly:
class Program
{
const string interpolated = $"{firstName}"; // Name *firstName* does not exist
// in the current context
static void Main(string[] args)
{
var firstName = "fred";
Console.WriteLine(interpolated);
Console.ReadKey();
}
}
To answer your question:
There is no current mechanism provided by the framework to evaluate interpolated strings at runtime. Therefore, you cannot store strings and interpolate on the fly out of the box.
There are libraries that exist that handle runtime interpolation of strings.
According to this discussion on the Roslyn codeplex site, string interpolation will likely not be compatible with resource files (emphasis mine):
String interpolation could be neater and easier to debug than either String.Format or concatenation...
Dim y = $"Robot {name} reporting
{coolant.name} levels are {coolant.level}
{reactor.name} levels are {reactor.level}"
However, this example is fishy. Most professional programmers won't be writing
user-facing strings in code. Instead they'll be storing those strings in resources (.resw, .resx or .xlf) for reasons of localization. So there doesn't seem much use for string interpolation here.
Assuming that your question is more about how to localise interpolated strings in your source code, and not how to handle interpolated string resources...
Given the example code:
var name = "John";
var middlename = "W";
var surname = "Bloggs";
var text = $"My name is {name} {middlename} {surname}";
Console.WriteLine(text);
The output is obviously:
My name is John W Bloggs
Now change the text assignment to fetch a translation instead:
var text = Translate($"My name is {name} {middlename} {surname}");
Translate is implemented like this:
public static string Translate(FormattableString text)
{
return string.Format(GetTranslation(text.Format),
text.GetArguments());
}
private static string GetTranslation(string text)
{
return text; // actually use gettext or whatever
}
You need to provide your own implementation of GetTranslation; it will receive a string like "My name is {0} {1} {2}" and should use GetText or resources or similar to locate and return a suitable translation for this, or just return the original parameter to skip translation.
You will still need to document for your translators what the parameter numbers mean; the text used in the original code string doesn't exist at runtime.
If, for example, in this case GetTranslation returned "{2}. {0} {2}, {1}. Don't wear it out." (hey, localisation is not just about language!) then the output of the full program would be:
Bloggs. John Bloggs, W. Don't wear it out.
Having said this, while using this style of translation is easy to develop, it's hard to actually translate, since the strings are buried in the code and only surface at runtime. Unless you have a tool that can statically explore your code and extract all the translatable strings (without having to hit that code path at runtime), you're better off using more traditional resx files, since they inherently give you a table of text to be translated.
As already said in previous answers: you currently cannot load the format string at runtime (e.g. from resource files) for string interpolation because it is used at compile time.
If you don't care about the compile time feature and just want to have named placeholders, you could use something like this extension method:
public static string StringFormat(this string input, Dictionary<string, object> elements)
{
int i = 0;
var values = new object[elements.Count];
foreach (var elem in elements)
{
input = Regex.Replace(input, "{" + Regex.Escape(elem.Key) + "(?<format>[^}]+)?}", "{" + i + "${format}}");
values[i++] = elem.Value;
}
return string.Format(input, values);
}
Be aware that you cannot have inline expressions like {i+1} here and that this is not code with best performance.
You can use this with a dictionary you load from resource files or inline like this:
var txt = "Hello {name} on {day:yyyy-MM-dd}!".StringFormat(new Dictionary<string, object>
{
["name"] = "Joe",
["day"] = DateTime.Now,
});
String interpolation is difficult to combine with localization because the compiler prefers to translate it to string.Format(...), which does not support localization. However, there is a trick that makes it possible to combine localization and string interpolation; it is described near the end of this article.
Normally string interpolation is translated to string.Format, whose behavior cannot be customized. However, in much the same way as lambda methods sometimes become expression trees, the compiler will switch from string.Format to FormattableStringFactory.Create (a .NET 4.6 method) if the target method accepts a System.FormattableString object.
The problem is, the compiler prefers to call string.Format if possible, so if there were an overload of Localized() that accepted FormattableString, it would not work with string interpolation because the C# compiler would simply ignore it [because there is an overload that accepts a plain string]. Actually, it's worse than that: the compiler also refuses to use FormattableString when calling an extension method.
It can work if you use a non-extension method. For example:
static class Loca
{
public static string lize(this FormattableString message)
{ return message.Format.Localized(message.GetArguments()); }
}
Then you can use it like this:
public class Program
{
public static void Main(string[] args)
{
Localize.UseResourceManager(Resources.ResourceManager);
var name = "Dave";
Console.WriteLine(Loca.lize($"Hello, {name}"));
}
}
It's important to realize that the compiler converts the $"..." string into an old-fashioned format string. So in this example, Loca.lize actually receives "Hello, {0}" as the format string, not "Hello, {name}".
Using the Microsoft.CodeAnalysis.CSharp.Scripting package you can achieve this.
You will need to create an object to store the data in, below a dynamic object is used. You could also create an specific class with all the properties required. The reason to wrap the dynamic object in a class in described here.
public class DynamicData
{
public dynamic Data { get; } = new ExpandoObject();
}
You can then use it as shown below.
var options = ScriptOptions.Default
.AddReferences(
typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).GetTypeInfo().Assembly,
typeof(System.Runtime.CompilerServices.DynamicAttribute).GetTypeInfo().Assembly);
var globals = new DynamicData();
globals.Data.Name = "John";
globals.Data.MiddleName = "James";
globals.Data.Surname = "Jamison";
var text = "My name is {Data.Name} {Data.MiddleName} {Data.Surname}";
var result = await CSharpScript.EvaluateAsync<string>($"$\"{text}\"", options, globals);
This is compiling the snippet of code and executing it, so it is true C# string interpolation. Though you will have to take into account the performance of this as it is actually compiling and executing your code at runtime. To get around this performance hit if you could use CSharpScript.Create to compile and cache the code.
The C# 6.0 string interpolation won't help you if the format string is not in your C# source code. In that case, you will have to use some other solution, like this library.
If we use interpolation then we are thinking in terms of methods, not constants. In that case we could define our translations as methods:
public abstract class InterpolatedText
{
public abstract string GreetingWithName(string firstName, string lastName);
}
public class InterpolatedTextEnglish : InterpolatedText
{
public override string GreetingWithName(string firstName, string lastName) =>
$"Hello, my name is {firstName} {lastName}.";
}
We can then load an implementation of InterpolatedText for a specific culture. This also provides a way to implement fallback, as one implementation can inherit from another. If English is the default language and other implementations inherit from it, there will at least be something to display until a translation is provided.
This seems a bit unorthodox, but offers some benefits:
Primarily, the string used for interpolation is always stored in a strongly-typed method with clearly-specified arguments.
Given this: "Hello, my name is {0} {1}" can we determine that the placeholders represent first name and last name in that order? There will always be a method which matches values to placeholders, but there's less room for confusion when the interpolated string is stored with its arguments.
Similarly, if we store our translation strings in one place and use them in another, it becomes possible to modify them in a way that breaks the code using them. We can add {2} to a string which will be used elsewhere, and that code will fail at runtime.
Using string interpolation this is impossible. If our translation string doesn't match the available arguments it won't even compile.
There are drawbacks, although I see difficulty in maintaining any solution.
The greatest is portability. If your translation is coded in C# and you switch, it's not the easiest thing to export all of your translations.
It also means that if you wish to farm out translations to different individuals (unless you have one person who speaks everything) then the translators must modify code. It's easy code, but code nonetheless.
Interpolated strings can not refactored out from their (variable) scope because of using of the embedded variables in them.
The only way to relocate the string literal part is passing the scope bound variables as parameter to an other location, and mark their position in the string with special placeholders. However this solution is already "invented" and out there:
string.Format("literal with placeholers", parameters);
or some of advanced library (interpolating runtime), but using the very same concept (passing parameters).
Then you can refactor out the "literal with placeholers" to a resource.
Im trying to match properties in class. Example class:
public static string ComingSoonPage
{
get { return "/blog-coming-soon.aspx"; }
}
public static string EncodeBase64(string dataToEncode)
{
byte[] bytes = System.Text.ASCIIEncoding.UTF8.GetBytes(dataToEncode);
string returnValue = System.Convert.ToBase64String(bytes);
return returnValue;
}
Im using this kind of regex:
(?:public|private|protected)([\s\w]*)\s+(\w+)[^(]
It matches not only properties but also methods which is wrong. So i want remove from matches sentences that contains (. So it select all but not methods (which contains ( ). How can i achieve that.
Try matching the "{" and the "get {" instead
(public|private|protected|internal)[\s\w]*\s+(\w+)\s*\{\s*get\s*\{
UPDATE
Match only the name of the property
(?<=(public|private|protected|internal)[\s\w]*\s+)\w+(?=\s*\{\s*get\s*\{)
uses the general pattern
(?<=prefix)find(?=suffix)
EDIT
A property might have no modifier (public, private etc.) at all and the type might contain extra characters (e.g. for arrays int[,]. Therefore it would probably be better to test only for the syntax elements following the property name (and the name itself). Also a property could consist of only a setter and be abstract: abstract int[,] Matrix { set; }. I suggest retrieving the property names like this:
\w+(?=\s*\{\s*(get|set)\b)
where \b matches a word beginning or (in this case) a word end.
This may be what you are looking for and this works perfectly! I deserve some treat though :)...
Regex r=new Regex(#"(public|private).*?(?=(public|private|$))",RegexOptions.Singleline);
Regex nr=new Regex(#"\(.*?\)\s+\{",RegexOptions.Singleline);
foreach(Match m in r.Matches(yourCodeFile))//extracts all methods and properties
{
if(!nr.IsMatch(m.Value))//shoots down methods
m.Value;//properties only
}
According to this answer, try using:
for Properties: type and name:
(?:public\s|private\s|protected\s|internal\s)\s*(?:readonly|static\s+)?(?<type>\w+)\s+(?<name>\w+)[\s\r\n]*{
for Fields: type and name:
(?:public\s|private\s|protected\s)\s*(?:readonly|static\s+)?(?<type>\w+)\s+(?<name>\w+);
for Methods: methodName and parameterType and parameter:
(?:public\s|private\s|protected\s|internal\s)?[\s\w]*\s+(?<methodName>\w+)\s*\(\s*(?:(ref\s|/in\s|out\s)?\s*(?<parameterType>\w+)\s+(?<parameter>\w+)\s*,?\s*)+\)
for c# code analysis try Irony or The Roslyn Project, see this sample:
C# and VB.NET Code Searcher - Using Roslyn codeproject
Is there any way to put spaces in a C# enum constant? I've read that you can do it in VB by doing this:
Public Enum EnumWithSpaces
ConstantWithoutSpaces
[Constant With Spaces]
End Enum
...and then access it like this:
Public Sub UsingEnumWithSpaces()
Dim foo As EnumWithSpaces = EnumWithSpaces.[Constant With Spaces]
End Sub
That implies to me that the CLR can handle an enum with spaces.
Is there any way to do this in C#?
This blog post might help you:
http://blog.spontaneouspublicity.com/2008/01/17/associating-strings-with-enums-in-c/
From the article:
But enums can't have spaces in C#!"
you say. Well, I like to use the
System.ComponentModel.DescriptionAttribute
to add a more friendly description to
the enum values. The example enum can
be rewritten like this:
public enum States
{
California,
[Description("New Mexico")]
NewMexico,
[Description("New York")]
NewYork,
[Description("South Carolina")]
SouthCarolina,
Tennessee,
Washington
}
Notice that I do not put descriptions on items where the ToString() version of that item displays just fine.
CLR can handle absolutely any character in identifiers. However, C# restricts the identifier characters to those legal under the CLS, which space isn't. Same goes for VB.NET, by the way - spaces inside square brackets used to work in VB6, but they don't in VB.NET.
If you're working with Visual C# 3.0 or above I've found it convenient to just extend the enum class and use a regex to inset spaces where neccessary:
public static class EnumExtension
{
public static String ToDisplayString(this Enum e)
{
Regex regex = new Regex(#"([^\^])([A-Z][a-z$])");
return regex.Replace(e.ToString(), new MatchEvaluator(m =>
{
return String.Format("{0} {1}", m.Groups[1].Value, m.Groups[2].Value);
}));
}
}
Notice this allows you to work with any enum as is without adding descriptions to every value.
String enumWithSpaces = MessageBoxButtons.OKCancel.ToDisplayString();