Tách CamelCase


80

Đây là tất cả asp.net c #.

Tôi có một enum

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

Giá trị số của điều này được lưu trữ trong cơ sở dữ liệu của tôi. Tôi hiển thị giá trị này trong một lưới dữ liệu.

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

ID không có ý nghĩa gì đối với người dùng vì vậy tôi đã thay đổi cột liên kết thành cột mẫu với phần sau.

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

Điều này tốt hơn rất nhiều ... Tuy nhiên, sẽ thật tuyệt nếu có một chức năng đơn giản mà tôi có thể đặt xung quanh Enum để chia nó theo trường hợp Camel để các từ nằm gọn trong datagrid.

Lưu ý: Tôi hoàn toàn nhận thức được rằng có nhiều cách tốt hơn để làm tất cả những điều này. Màn hình này hoàn toàn được sử dụng trong nội bộ và tôi chỉ muốn hack nhanh để hiển thị nó tốt hơn một chút.

Câu trả lời:


76

Thật vậy, regex / Replace là cách để đi như được mô tả trong câu trả lời khác, tuy nhiên điều này cũng có thể hữu ích cho bạn nếu bạn muốn đi theo một hướng khác

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

điều này sẽ cho phép bạn xác định Enums của mình là

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

Được lấy từ

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


+1 Câu trả lời tuyệt vời, tôi có thể sẽ sử dụng câu trả lời biểu thức chính quy vì nó nhanh hơn và dễ dàng hơn, tuy nhiên, đây là một giải pháp tốt hơn nhiều và vì vậy được chấp nhận.
— Ngày Robin

Tôi đã thấy nhiều câu trả lời về thuộc tính enum, nhưng điều này có vẻ rõ ràng nhất!
— nawfal,

2
thông minh, nhưng nó còn nhiều việc hơn một hàm regex tĩnh đơn giản. Tôi không chắc mình đồng ý với "sạch sẽ nhất" hoặc "nhanh hơn" hoặc "dễ dàng hơn". Người thông minh? chắc chắn.
— Todd Painton

1
Điều này chỉ hoạt động nếu bạn có quyền kiểm soát enum đó, nhưng tôi thà có toàn quyền kiểm soát mã hiển thị hơn là giả định rằng các giá trị enum sẽ được đánh vần một cách thuần thục.
— Berin Loritsch

131

Tôi đã sử dụng:

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

Lấy từ http://weblogs.asp.net/jgalloway/archive/2005/09/27/426087.aspx

vb.net:

Public Shared Function SplitCamelCase(ByVal input As String) As String
    Return System.Text.RegularExpressions.Regex.Replace(input, "([A-Z])", " $1", System.Text.RegularExpressions.RegexOptions.Compiled).Trim()
End Function

Cách đơn giản để hoàn thành phần vỏ lạc đà ... cách tiếp cận khác tốt hơn để tùy chỉnh nhiều hơn. Cảm ơn @Tillito
— rolivares

62
Tôi đã chỉnh sửa một chút biểu thức chính quy thành "(? <= [Az]) ([AZ])". Điều này dẫn đến việc ProductID được chuyển đổi thành ID Sản phẩm thay vì Sản phẩm I D. Nó chỉ định rằng chữ cái viết hoa phải được đặt trước một chữ cái viết thường (lưu ý toán tử lookbehind). Nó cũng loại bỏ sự cần thiết phải trang trí.
— Ben Mills

7
Này Ben, tại sao bạn không đặt nó như một câu trả lời. Có một regex khác (và phức tạp hơn) tạo thành một người bạn đời mới!
— Nicholas Petersen

3
Ngoài nhận xét hữu ích của Ben, tôi nên đề cập rằng bạn cũng có thể tách một cái gì đó như "HELLOWorld" thành "HELLO World" bằng cách sử dụng biểu thức chính quy: (? <= [AZ]) ([AZ]) (? = [Az] )
— giangurgolo

6
Tôi đã kết hợp các biểu thức của Ben Mills và giangurgolo: Regex.Replace (input, @ "((? <= [AZ]) ([AZ]) (? = [Az])) | ((? <= [Az] +) ([AZ])) ", @" $ 0 ", RegexOptions.Compiled) .Trim ();
— IceWarrior353,

23

Regex này (^[a-z]+|[A-Z]+(?![a-z])|[A-Z][a-z]+)có thể được sử dụng để trích xuất tất cả các từ từ tên camelCase hoặc PascalCase. Nó cũng hoạt động với các chữ viết tắt ở bất kỳ đâu bên trong tên.

  • MyHTTPServersẽ chứa đúng 3 trận đấu: My, HTTP,Server
  • myNewXMLFilesẽ chứa 4 trận đấu: my, New, XML,File

Sau đó, bạn có thể nối chúng thành một chuỗi duy nhất bằng cách sử dụng string.Join.

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

2
Tôi thích nó. Tuy nhiên, chúng ta đang sống trong thời hiện đại. Do đó: @"(^\p{Ll}+|\p{Lu}+(?!\p{Ll})|\p{Lu}\p{Ll}+)"Điều quan trọng cần lưu ý là điều này sẽ không thực hiện các con số, mặc dù chúng hợp lệ trong số nhận dạng.
— Daniel B

Đơn giản nhưng hoàn hảo!
— JC Raja

1
Tôi cần một chút thay đổi đối với "(^ [az] + | [AZ] + (?! [Az]) | [AZ] [az] + | [0-9 \. *] + | [Az] +)" "ITPortfolio12v2.0.13BMS" cho kết quả là "IT Portfolio 12 v 2.0.13 BMS" hth ai đó
— Joe Johnston

15

Nếu C # 3.0 là một tùy chọn, bạn có thể sử dụng một lớp lót sau để thực hiện công việc:


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

1
Điều này không xử lý Acroynms trong văn bản như AMACharter, trả về 'Điều lệ' chứ không phải 'Điều lệ AMA'.
— Adam Mills

Mặc dù việc sửa đổi để xử lý một trường hợp như vậy sẽ dễ dàng (hãy nghĩ đến việc viết trước một cái gì đó như ([AZ] *) và sửa đổi một chút mã), từ những gì tôi nhớ lại về hướng dẫn mã hóa của Microsoft, việc sử dụng các từ viết tắt viết hoa như vậy không được khuyến khích, và trong nên tránh các từ viết tắt viết hoa toàn bộ nếu dài hơn 2 chữ cái.
— em70

1
Không hiệu quả với tôi. "CamelCase" trở thành "Camel" chứ không phải "Camel Case".
— Tillito

15

Câu trả lời của Tillito không xử lý tốt các chuỗi đã chứa khoảng trắng, hoặc Từ viết tắt. Điều này khắc phục nó:

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

Tuyên bố từ chối trách nhiệm: tín dụng thuộc về Tillito, nhà cung cấp câu trả lời ban đầu và Ben Mills, người đã đề xuất cải tiến trong một nhận xét. Vì đó là một câu trả lời đã được cải thiện và không ai trong số họ đăng hoặc chỉnh sửa nó, nên nó xứng đáng có một câu trả lời riêng. Sẽ giúp tôi tiết kiệm nửa giờ gỡ lỗi nếu nó không bị chôn vùi dưới các bình luận để bắt đầu.
— Petrucio

2
Không thành công với trường hợp thử nghiệm đơn giản "SMSMessage" (dự kiến: "Tin nhắn SMS", thực tế: "SMSMessage").
— Ian Kemp

10

Đây là một phương thức mở rộng có thể xử lý các số và nhiều ký tự viết hoa một cách thuần thục và cũng cho phép viết hoa các từ viết tắt cụ thể trong chuỗi cuối cùng:

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

6

Bạn có thể sử dụng các phương thức mở rộng C #

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

Sau đó, bạn có thể sử dụng nó như

var result = "TestString".SpacesFromCamel();

Kết quả sẽ là

Chuỗi kiểm tra


1
Điều này thực sự tạo ra một khoảng trống ở phần đầu, đã sửa mã
— Martin Zikmund 22/02/19

2

Sử dụng 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
Bạn nên di chuyển trở lại để mã hóa với C \ C ++: D - cách quá bẩn cho C #
— dữ liệu

1
Tôi đã nói rằng đó là một vụ hack nhanh chóng và bẩn thỉu. Đây là phiên bản LINQ rõ ràng hơn.
— Andy Rose

Điều này không xử lý Acroynms trong văn bản như AMACharter, trả về 'AMA Charter' chứ không phải 'AMA Charter
— Adam Mills

2
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

Giải pháp từ Eoin Campbell hoạt động tốt trừ khi bạn có Dịch vụ web.

Bạn sẽ cần thực hiện những điều sau vì Thuộc tính mô tả không thể tuần tự hóa.

[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

Và nếu bạn không thích sử dụng regex - hãy thử điều này:

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

    }

Vượt qua những bài kiểm tra này, nó không thích những con số nhưng tôi không cần nó.

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

    }

2

Tôi cũng có một enumcái mà tôi phải tách ra. Trong trường hợp của tôi, phương pháp này đã giải quyết được vấn đề-

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

2

#JustSayNoToRegex

Lấy một mã định danh C #, với các udercores và số, và chuyển nó thành chuỗi được phân tách bằng dấu cách.

public static class StringExtensions
{
    public static string SplitOnCase(this string identifier)
    {
        if (identifier == null || identifier.Length == 0) return string.Empty;
        var sb = new StringBuilder();

        if (identifier.Length == 1) sb.Append(char.ToUpperInvariant(identifier[0]));

        else if (identifier.Length == 2) sb.Append(char.ToUpperInvariant(identifier[0])).Append(identifier[1]);

        else {
            if (identifier[0] != '_') sb.Append(char.ToUpperInvariant(identifier[0]));
            for (int i = 1; i < identifier.Length; i++) {
                var current = identifier[i];
                var previous = identifier[i - 1];

                if (current == '_' && previous == '_') continue;

                else if (current == '_') {
                    sb.Append(' ');
                }

                else if (char.IsLetter(current) && previous == '_') {
                    sb.Append(char.ToUpperInvariant(current));
                }

                else if (char.IsDigit(current) && char.IsLetter(previous)) {
                    sb.Append(' ').Append(current);
                }

                else if (char.IsLetter(current) && char.IsDigit(previous)) {
                    sb.Append(' ').Append(char.ToUpperInvariant(current));
                }

                else if (char.IsUpper(current) && char.IsLower(previous) 
                    && (i < identifier.Length - 1 && char.IsUpper(identifier[i + 1]) || i == identifier.Length - 1)) {
                        sb.Append(' ').Append(current);
                }

                else if (char.IsUpper(current) && i < identifier.Length - 1 && char.IsLower(identifier[i + 1])) {
                    sb.Append(' ').Append(current);
                }

                else {
                    sb.Append(current);
                }
            }
        }
        return sb.ToString();
    }

}

Kiểm tra:

[TestFixture]
static class HelpersTests
{
    [Test]
    public static void Basic()
    {
        Assert.AreEqual("Foo", "foo".SplitOnCase());
        Assert.AreEqual("Foo", "_foo".SplitOnCase());
        Assert.AreEqual("Foo", "__foo".SplitOnCase());
        Assert.AreEqual("Foo", "___foo".SplitOnCase());
        Assert.AreEqual("Foo 2", "foo2".SplitOnCase());
        Assert.AreEqual("Foo 23", "foo23".SplitOnCase());
        Assert.AreEqual("Foo 23 A", "foo23A".SplitOnCase());
        Assert.AreEqual("Foo 23 Ab", "foo23Ab".SplitOnCase());
        Assert.AreEqual("Foo 23 Ab", "foo23_ab".SplitOnCase());
        Assert.AreEqual("Foo 23 Ab", "foo23___ab".SplitOnCase());
        Assert.AreEqual("Foo 23", "foo__23".SplitOnCase());
        Assert.AreEqual("Foo Bar", "Foo_bar".SplitOnCase());
        Assert.AreEqual("Foo Bar", "Foo____bar".SplitOnCase());
        Assert.AreEqual("AAA", "AAA".SplitOnCase());
        Assert.AreEqual("Foo A Aa", "fooAAa".SplitOnCase());
        Assert.AreEqual("Foo AAA", "fooAAA".SplitOnCase());
        Assert.AreEqual("Foo Bar", "FooBar".SplitOnCase());
        Assert.AreEqual("Mn M", "MnM".SplitOnCase());
        Assert.AreEqual("AS", "aS".SplitOnCase());
        Assert.AreEqual("As", "as".SplitOnCase());
        Assert.AreEqual("A", "a".SplitOnCase());
        Assert.AreEqual("_", "_".SplitOnCase());

    }
}

1

Phiên bản đơn giản tương tự như một số phiên bản ở trên, nhưng với logic để không tự động chèn dấu phân cách (theo mặc định là dấu cách, nhưng có thể là bất kỳ ký tự nào) nếu đã có một ký tự ở vị trí hiện tại.

Sử dụng một chuỗi StringBuilderthay vì 'đột biến'.

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

Thí dụ:

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

Thử cái này:

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';
    }
}

Xem mẫu trực tuyến

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.