Spaccare CamelCase

Questo è tutto asp.net c #.

Ho un enume

public enum ControlSelectionType { NotApplicable = 1, SingleSelectRadioButtons = 2, SingleSelectDropDownList = 3, MultiSelectCheckBox = 4, MultiSelectListBox = 5 } 

Il valore numerico di questo è memorizzato nel mio database. Visualizzo questo valore in un datagrid.

  

L’ID non significa nulla per un utente, quindi ho cambiato il boundcolumn in una colonna modello con il seguente.

      

Questo è molto meglio … Comunque, sarebbe bello se ci fosse una semplice funzione che posso mettere attorno all’Enum per dividerlo dal caso Camel in modo che le parole avvolgano bene nel datagrid.

Nota: sono pienamente consapevole del fatto che ci sono modi migliori per fare tutto questo. Questo schermo è puramente utilizzato internamente e voglio solo un rapido trucco per visualizzarlo un po ‘meglio.

Effettivamente una regex / replace è la strada da percorrere come descritto nell’altra risposta, tuttavia questo potrebbe essere utile anche a te se volessi andare in una direzione diversa

  using System.ComponentModel; using System.Reflection; 

  public static string GetDescription(System.Enum value) { FieldInfo fi = value.GetType().GetField(value.ToString()); DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes.Length > 0) return attributes[0].Description; else return value.ToString(); } 

questo ti permetterà di definire il tuo Enum come

 public enum ControlSelectionType { [Description("Not Applicable")] NotApplicable = 1, [Description("Single Select Radio Buttons")] SingleSelectRadioButtons = 2, [Description("Completely Different Display Text")] SingleSelectDropDownList = 3, } 

Preso da

http://www.codeguru.com/forum/archive/index.php/t-412868.html

Ero solito:

  public static string SplitCamelCase(string input) { return System.Text.RegularExpressions.Regex.Replace(input, "([AZ])", " $1", System.Text.RegularExpressions.RegexOptions.Compiled).Trim(); } 

Tratto da http://weblogs.asp.net/jgalloway/archive/2005/09/27/426087.aspx

Questa regex (^[az]+|[AZ]+(?![az])|[AZ][az]+) può essere utilizzata per estrarre tutte le parole dal nome CamelCase o PascalCase. Funziona anche con abbreviazioni ovunque all’interno del nome.

  • MyHTTPServer conterrà esattamente 3 corrispondenze: My , HTTP , Server
  • myNewXMLFile conterrà 4 corrispondenze: my , New , XML , File

Potresti quindi unirli a una singola stringa usando string.Join .

 string name = "myNewUIControl"; string[] words = Regex.Matches(name, "(^[az]+|[AZ]+(?![az])|[AZ][az]+)") .OfType() .Select(m => m.Value) .ToArray(); string result = string.Join(" ", words); 

Se C # 3.0 è un’opzione, puoi utilizzare il seguente one-liner per eseguire il lavoro:

 Regex.Matches(YOUR_ENUM_VALUE_NAME, "[AZ][az]+").OfType().Select(match => match.Value).Aggregate((acc, b) => acc + " " + b).TrimStart(' '); 

La risposta di Tillito non gestisce le stringhe che contengono bene spazi, o acronimi. Questo lo risolve:

 public static string SplitCamelCase(string input) { return Regex.Replace(input, "(?< =[az])([AZ])", " $1", RegexOptions.Compiled); } 

Ecco un metodo di estensione che gestisce i numeri e i caratteri maiuscoli multipli, e consente anche gli acronimi specifici della parte superiore della stringa finale:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Globalization; using System.Text.RegularExpressions; using System.Web.Configuration; namespace System { ///  /// Extension methods for the string data type ///  public static class ConventionBasedFormattingExtensions { ///  /// Turn CamelCaseText into Camel Case Text. ///  ///  ///  /// Use AppSettings["SplitCamelCase_AllCapsWords"] to specify a comma-delimited list of words that should be ALL CAPS after split ///  /// wordWordIDWord1WordWORDWord32Word2 /// Word Word ID Word 1 Word WORD Word 32 Word 2 /// /// wordWordIDWord1WordWORDWord32WordID2ID /// Word Word ID Word 1 Word WORD Word 32 Word ID 2 ID /// /// WordWordIDWord1WordWORDWord32Word2Aa /// Word Word ID Word 1 Word WORD Word 32 Word 2 Aa /// /// wordWordIDWord1WordWORDWord32Word2A /// Word Word ID Word 1 Word WORD Word 32 Word 2 A ///  public static string SplitCamelCase(this string input) { if (input == null) return null; if (string.IsNullOrWhiteSpace(input)) return ""; var separated = input; separated = SplitCamelCaseRegex.Replace(separated, @" $1").Trim(); //Set ALL CAPS words if (_SplitCamelCase_AllCapsWords.Any()) foreach (var word in _SplitCamelCase_AllCapsWords) separated = SplitCamelCase_AllCapsWords_Regexes[word].Replace(separated, word.ToUpper()); //Capitalize first letter var firstChar = separated.First(); //NullOrWhiteSpace handled earlier if (char.IsLower(firstChar)) separated = char.ToUpper(firstChar) + separated.Substring(1); return separated; } private static readonly Regex SplitCamelCaseRegex = new Regex(@" ( (?< =[az])[A-Z0-9] (?# lower-to-other boundaries ) | (?<=[0-9])[a-zA-Z] (?# number-to-other boundaries ) | (?<=[AZ])[0-9] (?# cap-to-number boundaries; handles a specific issue with the next condition ) | (?<=[AZ])[AZ](?=[az]) (?# handles longer strings of caps like ID or CMS by splitting off the last capital ) )" , RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace ); private static readonly string[] _SplitCamelCase_AllCapsWords = (WebConfigurationManager.AppSettings["SplitCamelCase_AllCapsWords"] ?? "") .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(a => a.ToLowerInvariant().Trim()) .ToArray() ; private static Dictionary _SplitCamelCase_AllCapsWords_Regexes; private static Dictionary SplitCamelCase_AllCapsWords_Regexes { get { if (_SplitCamelCase_AllCapsWords_Regexes == null) { _SplitCamelCase_AllCapsWords_Regexes = new Dictionary(); foreach(var word in _SplitCamelCase_AllCapsWords) _SplitCamelCase_AllCapsWords_Regexes.Add(word, new Regex(@"\b" + word + @"\b", RegexOptions.Compiled | RegexOptions.IgnoreCase)); } return _SplitCamelCase_AllCapsWords_Regexes; } } } } 
 public enum ControlSelectionType { NotApplicable = 1, SingleSelectRadioButtons = 2, SingleSelectDropDownList = 3, MultiSelectCheckBox = 4, MultiSelectListBox = 5 } public class NameValue { public string Name { get; set; } public object Value { get; set; } } public static List EnumToList(bool camelcase) { var array = (T[])(Enum.GetValues(typeof(T)).Cast()); var array2 = Enum.GetNames(typeof(T)).ToArray(); List lst = null; for (int i = 0; i < array.Length; i++) { if (lst == null) lst = new List(); string name = ""; if (camelcase) { name = array2[i].CamelCaseFriendly(); } else name = array2[i]; T value = array[i]; lst.Add(new NameValue { Name = name, Value = value }); } return lst; } public static string CamelCaseFriendly(this string pascalCaseString) { Regex r = new Regex("(?< =[az])(?[AZ])|(?< =.)(?[AZ])(?=[az])"); return r.Replace(pascalCaseString, " ${x}"); } //In your form protected void Button1_Click1(object sender, EventArgs e) { DropDownList1.DataSource = GeneralClass.EnumToList(true); ; DropDownList1.DataTextField = "Name"; DropDownList1.DataValueField = "Value"; DropDownList1.DataBind(); } 

La soluzione di Eoin Campbell funziona correttamente, tranne se si dispone di un servizio Web.

Dovresti fare quanto segue in quanto l’attributo Descrizione non è serializzabile.

 [DataContract] public enum ControlSelectionType { [EnumMember(Value = "Not Applicable")] NotApplicable = 1, [EnumMember(Value = "Single Select Radio Buttons")] SingleSelectRadioButtons = 2, [EnumMember(Value = "Completely Different Display Text")] SingleSelectDropDownList = 3, } public static string GetDescriptionFromEnumValue(Enum value) { EnumMemberAttribute attribute = value.GetType() .GetField(value.ToString()) .GetCustomAttributes(typeof(EnumMemberAttribute), false) .SingleOrDefault() as EnumMemberAttribute; return attribute == null ? value.ToString() : attribute.Value; } 

È ansible utilizzare i metodi di estensione C #

  public static string SpacesFromCamel(this string value) { if (value.Length > 0) { var result = new List(); char[] array = value.ToCharArray(); foreach (var item in array) { if (char.IsUpper(item)) { result.Add(' '); } result.Add(item); } return new string(result.ToArray()); } return value; } 

Quindi puoi usarlo come

 var result = "TestString".SpacesFromCamel(); 

Il risultato sarà

Test String

Utilizzando LINQ:

 var chars = ControlSelectionType.NotApplicable.ToString().SelectMany((x, i) => i > 0 && char.IsUpper(x) ? new char[] { ' ', x } : new char[] { x }); Console.WriteLine(new string(chars.ToArray())); 

E se non ti piace usare regex, prova questo:

 public static string SeperateByCamelCase(this string text, char splitChar = ' ') { var output = new StringBuilder(); for (int i = 0; i < text.Length; i++) { var c = text[i]; //if not the first and the char is upper if (i > 0 && char.IsUpper(c)) { var wasLastLower = char.IsLower(text[i - 1]); if (i + 1 < text.Length) //is there a next { var isNextUpper = char.IsUpper(text[i + 1]); if (!isNextUpper) //if next is not upper (start of a word). { output.Append(splitChar); } else if (wasLastLower) //last was lower but i'm upper and my next is an upper (start of an achromin). 'abcdHTTP' 'abcd HTTP' { output.Append(splitChar); } } else { //last letter - if its upper and the last letter was lower 'abcd' to 'abcd A' if (wasLastLower) { output.Append(splitChar); } } } output.Append(c); } return output.ToString(); } 

Supera questi test, non mi piacciono i numeri ma non ne ho avuto bisogno.

  [TestMethod()] public void ToCamelCaseTest() { var testData = new string[] { "AAACamel", "AAA", "SplitThisByCamel", "AnA", "doesnothing", "a", "A", "aasdasdAAA" }; var expectedData = new string[] { "AAA Camel", "AAA", "Split This By Camel", "An A", "doesnothing", "a", "A", "aasdasd AAA" }; for (int i = 0; i < testData.Length; i++) { var actual = testData[i].SeperateByCamelCase(); var expected = expectedData[i]; Assert.AreEqual(actual, expected); } } 

Ho anche un enum che ho dovuto separare. Nel mio caso questo metodo ha risolto il problema-

 string SeparateCamelCase(string str) { for (int i = 1; i < str.Length; i++) { if (char.IsUpper(str[i])) { str = str.Insert(i, " "); i++; } } return str; } 

Prova questo:

 using System; using System.Linq; using System.Collections.Generic; public class Program { public static void Main() { Console .WriteLine( SeparateByCamelCase("TestString") == "Test String" // True ); } public static string SeparateByCamelCase(string str) { return String.Join(" ", SplitByCamelCase(str)); } public static IEnumerable SplitByCamelCase(string str) { if (str.Length == 0) return new List(); return new List { Head(str) } .Concat( SplitByCamelCase( Tail(str) ) ); } public static string Head(string str) { return new String( str .Take(1) .Concat( str .Skip(1) .TakeWhile(IsLower) ) .ToArray() ); } public static string Tail(string str) { return new String( str .Skip( Head(str).Length ) .ToArray() ); } public static bool IsLower(char ch) { return ch >= 'a' && ch < = 'z'; } } 

Vedi campione online