it-swarm.com.de

CamelCase aufteilen

Dies ist alles asp.net c #.

Ich habe eine enum

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

Der numerische Wert davon wird in meiner Datenbank gespeichert. Ich zeige diesen Wert in einem Datagrid.

<asp:boundcolumn datafield="ControlSelectionTypeId" headertext="Control Type"></asp:boundcolumn>

Die ID bedeutet für einen Benutzer nichts, daher habe ich die gebundene Spalte in eine Vorlagenspalte mit folgendem geändert.

<asp:TemplateColumn>
    <ItemTemplate>
        <%# Enum.Parse(typeof(ControlSelectionType), DataBinder.Eval(Container.DataItem, "ControlSelectionTypeId").ToString()).ToString()%>
    </ItemTemplate>
</asp:TemplateColumn>

Das ist viel besser ... Es wäre jedoch toll, wenn es eine einfache Funktion gibt, die ich um das Enum legen kann, um es nach Camel-Fällen aufzuteilen, so dass die Wörter schön in das Datagrid passen.

Hinweis: Ich bin mir bewusst, dass es bessere Wege gibt, dies alles zu tun. Dieser Bildschirm wird rein intern verwendet und ich möchte nur einen schnellen Hack, um ihn etwas besser darzustellen.

66
Robin Day

Ein Regex/Ersetzen ist zwar der Weg, wie in der anderen Antwort beschrieben. Dies kann jedoch auch für Sie von Nutzen sein, wenn Sie in eine andere Richtung gehen möchten

    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();
    }

dadurch können Sie Ihre Enums als definieren

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

Genommen von

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

72
Eoin Campbell

Ich benutzte:

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

Entnommen aus http://weblogs.asp.net/jgalloway/archive/2005/09/27/426087.aspx

103
Tillito

Mit diesem Regex (^[a-z]+|[A-Z]+(?![a-z])|[A-Z][a-z]+) können alle Wörter aus dem Namen von camelCase oder PascalCase extrahiert werden. Es funktioniert auch mit Abkürzungen innerhalb des Namens.

  • MyHTTPServer enthält genau 3 Treffer: My, HTTP, Server
  • myNewXMLFile enthält 4 Treffer: my, New, XML, File

Sie können sie dann mit string.Join zu einer einzigen Zeichenfolge zusammenfügen.

string name = "myNewUIControl";
string[] words = Regex.Matches(name, "(^[a-z]+|[A-Z]+(?![a-z])|[A-Z][a-z]+)")
    .OfType<Match>()
    .Select(m => m.Value)
    .ToArray();
string result = string.Join(" ", words);
19
Ghost4Man

Wenn C # 3.0 eine Option ist, können Sie den folgenden Einzeiler verwenden, um die Aufgabe auszuführen:


Regex.Matches(YOUR_ENUM_VALUE_NAME, "[A-Z][a-z]+").OfType<Match>().Select(match => match.Value).Aggregate((acc, b) => acc + " " + b).TrimStart(' ');
14
em70

Tillitos Antwort behandelt Zeichenfolgen, die bereits Leerzeichen enthalten, oder Akronyme nicht. Das behebt es:

public static string SplitCamelCase(string input)
{
    return Regex.Replace(input, "(?<=[a-z])([A-Z])", " $1", RegexOptions.Compiled);
}
12
Petrucio

Hier ist eine Erweiterungsmethode, die Zahlen und mehrere Großbuchstaben auf sanfte Weise behandelt und außerdem in der abschließenden Zeichenfolge Großbuchstaben-spezifische Akronyme zulässt:

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
{
    /// <summary>
    /// Extension methods for the string data type
    /// </summary>
    public static class ConventionBasedFormattingExtensions
    {
        /// <summary>
        /// Turn CamelCaseText into Camel Case Text.
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <remarks>Use AppSettings["SplitCamelCase_AllCapsWords"] to specify a comma-delimited list of words that should be ALL CAPS after split</remarks>
        /// <example>
        /// 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
        /// </example>
        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(@"
            (
                (?<=[a-z])[A-Z0-9] (?# lower-to-other boundaries )
                |
                (?<=[0-9])[a-zA-Z] (?# number-to-other boundaries )
                |
                (?<=[A-Z])[0-9] (?# cap-to-number boundaries; handles a specific issue with the next condition )
                |
                (?<=[A-Z])[A-Z](?=[a-z]) (?# 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<string, Regex> _SplitCamelCase_AllCapsWords_Regexes;
        private static Dictionary<string, Regex> SplitCamelCase_AllCapsWords_Regexes
        {
            get
            {
                if (_SplitCamelCase_AllCapsWords_Regexes == null)
                {
                    _SplitCamelCase_AllCapsWords_Regexes = new Dictionary<string,Regex>();
                    foreach(var Word in _SplitCamelCase_AllCapsWords)
                        _SplitCamelCase_AllCapsWords_Regexes.Add(Word, new Regex(@"\b" + Word + @"\b", RegexOptions.Compiled | RegexOptions.IgnoreCase));
                }

                return _SplitCamelCase_AllCapsWords_Regexes;
            }
        }
    }
}
8
Jerph

Sie können C # -Erweiterungsmethoden verwenden

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

                return new string(result.ToArray());
            }
            return value;
        }

Dann kannst du es gerne benutzen 

var result = "TestString".SpacesFromCamel();

Ergebnis wird sein 

Test String

3
Sameera R.
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<NameValue> EnumToList<T>(bool camelcase)
        {
            var array = (T[])(Enum.GetValues(typeof(T)).Cast<T>()); 
            var array2 = Enum.GetNames(typeof(T)).ToArray<string>(); 
            List<NameValue> lst = null;
            for (int i = 0; i < array.Length; i++)
            {
                if (lst == null)
                    lst = new List<NameValue>();
                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("(?<=[a-z])(?<x>[A-Z])|(?<=.)(?<x>[A-Z])(?=[a-z])");
            return r.Replace(pascalCaseString, " ${x}");
        }

//In  your form 
protected void Button1_Click1(object sender, EventArgs e)
        {
            DropDownList1.DataSource = GeneralClass.EnumToList<ControlSelectionType  >(true); ;
            DropDownList1.DataTextField = "Name";
            DropDownList1.DataValueField = "Value";

            DropDownList1.DataBind();
        }
2
Kiarash

Die Lösung von Eoin Campbell funktioniert gut, es sei denn, Sie haben einen Webservice.

Sie müssen Folgendes tun, da das Beschreibungsattribut nicht serialisierbar ist.

[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;
}
2
Theo Koekemoer

Verwendung von 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()));
1
Andy Rose

Ich habe auch eine enum, die ich trennen musste. In meinem Fall löste diese Methode das Problem.

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

Und wenn Sie Regex nicht mögen, probieren Sie folgendes:

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();

    }

Bestanden diese Tests, mag es keine Zahlen, aber ich brauchte es nicht.

    [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);
        }

    }
1
Hath

Versuche dies:

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<string> SplitByCamelCase(string str) 
    {
        if (str.Length == 0) 
            return new List<string>();

        return 
            new List<string> 
            { 
                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';
    }
}

Siehe Muster online

0
kogoia

Einfache Version, ähnlich wie einige der oben genannten, aber mit der Logik, dass das Trennzeichen (das standardmäßig ein Leerzeichen ist, aber ein beliebiges Zeichen sein kann) nicht automatisch eingefügt wird, wenn es an der aktuellen Position bereits eines gibt.

Verwendet ein StringBuilder anstatt 'mutierende' Zeichenketten.

public static string SeparateCamelCase(this string value, char separator = ' ') {

    var sb = new StringBuilder();
    var lastChar = separator;

    foreach (var currentChar in value) {

        if (char.IsUpper(currentChar) && lastChar != separator)
            sb.Append(separator);

        sb.Append(currentChar);

        lastChar = currentChar;
    }

    return sb.ToString();
}

Beispiel:

Input  : 'ThisIsATest'
Output : 'This Is A Test'

Input  : 'This IsATest'
Output : 'This Is A Test' (Note: Still only one space between 'This' and 'Is')

Input  : 'ThisIsATest' (with separator '_')
Output : 'This_Is_A_Test'
0
MarqueIV