Tạo chữ cái đầu tiên của chữ hoa (với hiệu suất tối đa)


447

Tôi có một DetailsViewvới một TextBox và tôi muốn các dữ liệu đầu vào be luôn lưu với BÀI ĐẦU TIÊN TRONG VỐN.

Thí dụ:

"red" --> "Red"
"red house" --> " Red house"

Làm thế nào tôi có thể đạt được hiệu suất tối đa này ?


LƯU Ý :
Dựa trên các câu trả lời và các ý kiến ​​dưới các câu trả lời, nhiều người nghĩ rằng đây là hỏi về cách viết hoa tất cả các từ trong chuỗi. Ví dụ: => Red House Nó không phải là, nhưng nếu đó là những gì bạn tìm kiếm , xem xét cho một trong những câu trả lời mà công dụng TextInfocủa ToTitleCasephương pháp. (Chú ý: Những câu trả lời là không chính xác . Cho câu hỏi thực sự hỏi)
Xem TextInfo.ToTitleCase doc cho cẩn thận (không chạm vào tất cả mũ từ - họ là coi từ viết tắt; có thể thành chữ thường chữ ở giữa của từ mà "không nên" được hạ xuống, ví dụ "McDonald" => "Mcdonald"; không được bảo đảm để xử lý tất cả các quy tắc viết hoa đặc trưng cho văn hóa.)


Chú ý :
Câu hỏi đặt ra là mơ hồ về việc liệu chữ sau khi người đầu tiên nên được buộc để giảm trường hợp . Câu trả lời được chấp nhận giả định rằng chỉ nên thay đổi chữ cái đầu tiên . Nếu bạn muốn buộc tất cả các chữ cái trong chuỗi ngoại trừ chữ cái đầu tiên thành chữ thường, hãy tìm câu trả lời có chứa ToLowerkhông chứa ToTitleCase .


7
@ BOB: Đây không phải là một bản sao: OP yêu cầu viết hoa chữ cái đầu tiên của chuỗi, câu hỏi trong liên kết viết hoa chữ cái đầu tiên của mỗi từ.
GvS

1
@GvS: Câu trả lời đầu tiên rất chi tiết và khối mã đầu tiên chính xác là thứ anh ta đang tìm kiếm. Ngoài ra, giữa viết hoa mỗi từ và chỉ từ đầu tiên chỉ là một sự khác biệt vòng lặp.
Bobby

Bạn đã bao giờ có được giải quyết này thành công? Bạn vẫn cần giúp đỡ với điều này?
jcolebrand

1
Nhưng bạn đã nói, và tôi trích dẫn, "Tạo chữ cái đầu tiên của MACHI chữ hoa". Vì vậy, tại sao "nhà đỏ" -> "nhà đỏ"? Tại sao "h" của "house" không phải là chữ in hoa?
Guillermo Gutiérrez

Đã thêm một câu trả lời vì hầu hết các câu trả lời sẽ thất bại nếu bạn có một khoảng trắng khi bắt đầu. để tránh đăng bài này lên mỗi câu trả lời, tôi sẽ đăng nó ở đây một lần.
Noctis

Câu trả lời:


583

Đã cập nhật lên C # 8

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input) =>
        input switch
        {
            null => throw new ArgumentNullException(nameof(input)),
            "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
            _ => input.First().ToString().ToUpper() + input.Substring(1)
        };
}

C # 7

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input)
    {
        switch (input)
        {
            case null: throw new ArgumentNullException(nameof(input));
            case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
            default: return input.First().ToString().ToUpper() + input.Substring(1);
        }
    }
}

Câu trả lời thực sự cũ

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("ARGH!");
    return input.First().ToString().ToUpper() + String.Join("", input.Skip(1));
}

EDIT : Phiên bản này ngắn hơn. Để có giải pháp nhanh hơn, hãy xem câu trả lời của Equiso

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("ARGH!");
    return input.First().ToString().ToUpper() + input.Substring(1);
}

EDIT 2 : Có lẽ giải pháp nhanh nhất là của Darren (Thậm chí có điểm chuẩn) mặc dù tôi sẽ thay đổi string.IsNullOrEmpty(s)xác nhận của mình để đưa ra một ngoại lệ vì yêu cầu ban đầu mong muốn có một chữ cái đầu tiên tồn tại để nó có thể được viết hoa. Lưu ý rằng mã này hoạt động cho một chuỗi chung và không đặc biệt trên các giá trị hợp lệ từ Textbox.


2
Bởi vì tham số đầu tiên String.Joinlà dấu phân cách để nối các chuỗi được cung cấp với tham số thứ hai.
Dialecticus

27
Tôi thực sự thích câu trả lời của bạn, nhưng var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);có lẽ sẽ đạt được một số tốc độ vì bạn đang tạo ra các đối tượng ít bất biến hơn (và đặc biệt là bạn đang bỏ qua String.Join). Điều này tất nhiên phụ thuộc vào độ dài của chuỗi.
flindeberg

3
Tuyệt vời - Sử dụng Linq làm cho nó rất rõ những gì mã này làm.
Daniel James Bryars 27/11/13

7
Hmmm ... Về mặt kỹ thuật, điều này sẽ quay trở lại "Argh!"để tuân thủ quy tắc Chữ cái viết hoa chữ thường . ;)
jp2code

2
@ jp2code Kể từ khi viết hoa một chữ cái đầu tiên không tồn tại trong một chuỗi rỗng hoặc rỗng giống như bị tát bởi một con cá heo đang mang thai, thì TẤT CẢ CÁC CAPS ARGH! là cách viết đúng. urbandipedia.com/define.php?term=ARGH&defid=67839
Carlos Muñoz

319
public string FirstLetterToUpper(string str)
{
    if (str == null)
        return null;

    if (str.Length > 1)
        return char.ToUpper(str[0]) + str.Substring(1);

    return str.ToUpper();
}

Câu trả lời cũ: Điều này làm cho mỗi chữ cái đầu tiên viết hoa

public string ToTitleCase(string str)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}

Nhưng điều này chuyển đổi mọi chữ cái đầu tiên của một từ thành chữ hoa, không chỉ là ký tự đầu tiên của một chuỗi.
GvS

@GvS, đó là những gì câu hỏi yêu cầu bạn làm.
thattcarguy

17
Anh hỏi "nhà đỏ" => "nhà đỏ". ToTitleCase sẽ cung cấp cho bạn "Nhà đỏ".
GvS

1
hữu ích cho tôi Tuyệt vời
Ehsan Sajjad

1
Không chắc chắn về điều này nhưng char + chuỗi gây ra một quyền anh. Chỉ trong trường hợp hiệu suất tối đa là yêu cầu.
nawfal

163

Cách đúng đắn là sử dụng Văn hóa:

System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(word.ToLower())

Lưu ý: Điều này sẽ viết hoa từng từ trong một chuỗi, ví dụ "nhà đỏ" -> "Nhà đỏ". Giải pháp cũng sẽ viết hoa chữ thường trong các từ, ví dụ "McDonald cũ" -> "Old Mcdonald".


4
Đây là cách thích hợp nhất để làm điều đó hơn là phát minh lại bánh xe và cố gắng viết phiên bản của riêng bạn.
Alexey Shevelyov

12
Vấn đề tôi gặp phải là nó sẽ xóa các chữ in hoa có khả năng hợp lệ là chuỗi giữa. ví dụ: McNames
Jecoms

29
Đây là một câu trả lời không chính xác vì lý do "ngôi nhà đỏ" trở thành "Nhà đỏ" (chú ý "H")!
spaark

21
Sáu năm sau khi câu hỏi được hỏi, xin vui lòng làm một công việc kỹ lưỡng hơn là đọc câu trả lời hiện có và ý kiến ​​của họ . Nếu bạn tin rằng bạn có một giải pháp tốt hơn, thì hãy chỉ ra các tình huống trong đó câu trả lời của bạn hành xử theo cách bạn nghĩ là vượt trội, và cụ thể là nó khác với câu trả lời hiện có như thế nào. 1) Equiso đã bao gồm tùy chọn này, trong nửa sau câu trả lời của mình. 2) Đối với nhiều tình huống, ToLowerlà một sai lầm, vì nó xóa sạch chữ viết hoa ở giữa từ, ví dụ: "McDonalds". 3) Câu hỏi là về việc thay đổi chỉ từ đầu tiên của chuỗi , không phải về TitleCase.
ToolmakerSteve

10
Điều này biến đầu vào thành "Trường hợp tiêu đề" - vì vậy nó biến "ngựa đỏ" thành "Ngựa đỏ" - trong khi người hỏi tuyên bố rõ ràng rằng KHÔNG nên làm điều này (và trả lại "Ngựa đỏ"). Đây không phải là cách đúng đắn.
Hekkaryk

68

Tôi đã sử dụng phương thức nhanh nhất từ http://www.dotnetperls.com/uppercase-first-letter và chuyển đổi sang phương thức mở rộng:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase, or mutates any nulls passed into string.Empty
    /// </summary>
    public static string FirstLetterToUpperCaseOrConvertNullToEmptyString(this string s)
    {
        if (string.IsNullOrEmpty(s))
            return string.Empty;

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }

LƯU Ý: Lý do sử dụng ToCharArraynhanh hơn giải pháp thay thế char.ToUpper(s[0]) + s.Substring(1), là chỉ có một chuỗi được phân bổ, trong khi Substringcách tiếp cận phân bổ một chuỗi cho chuỗi con, sau đó là chuỗi thứ hai để tạo kết quả cuối cùng.


EDIT : Đây là cách tiếp cận này, kết hợp với thử nghiệm ban đầu từ câu trả lời được chấp nhận của CarlosMuñoz :

    /// <summary>
    /// Returns the input string with the first character converted to uppercase
    /// </summary>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrEmpty(s))
            throw new ArgumentException("There is no first letter");

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }

Ồ, cảm ơn vì đã tìm thấy số liệu hiệu suất, để hiển thị một giải pháp hiệu suất vượt trội!
ToolmakerSteve

@ToolmakerSteve, tôi thích giải pháp này vì nó thực sự có vẻ nhanh hơn các giải pháp khác nhưng có một chút vấn đề với nó. Nếu bạn vượt qua null, bạn không nên lấy một chuỗi rỗng làm đầu ra. Trong thực tế, tôi sẽ lập luận rằng ngay cả việc chuyển một chuỗi rỗng cũng sẽ tạo ra một ngoại lệ vì OP yêu cầu chữ cái đầu tiên . Ngoài ra, bạn có thể nhận xét về câu trả lời của người khác trước khi chỉnh sửa chúng.
Carlos Muñoz

@ CarlosMuñoz - nó đã được thảo luận trong meta, có nên "cải thiện" câu trả lời của người khác hay không. Sự đồng thuận là "nếu bạn có thể cải thiện câu trả lời, thì hãy làm như vậy - không ai 'sở hữu' một câu trả lời, ngay cả tác giả gốc - mục tiêu là có câu trả lời tốt nhất có thể". Bạn tất nhiên là miễn phí để chỉnh sửa hoặc khôi phục chỉnh sửa. Trong trường hợp đó, phép lịch sự thông thường sẽ cho phép phiên bản của tác giả ban đầu là kết quả cuối cùng và tôi sẽ giải quyết để bình luận. Thông thường tôi cũng đưa ra một nhận xét về sự thay đổi mà tôi đang thực hiện; Tôi xin lỗi nếu tôi không.
ToolmakerSteve

@ CarlosMuñoz - đặc biệt, có rất nhiều, rất nhiều câu trả lời trong SO, không được duy trì tích cực. Nếu một thay đổi sẽ cải thiện một câu trả lời, tại sao lại để nó bị chôn vùi trong một bình luận? Nếu tác giả đang tích cực theo dõi câu trả lời của họ, họ sẽ làm gì với sự thay đổi khi họ thấy phù hợp. Nếu họ không, thì câu trả lời đã được cải thiện, vì lợi ích của mọi người. Nguyên tắc này đặc biệt đúng, đối với các câu hỏi và trả lời cũ, chẳng hạn như câu hỏi này.
ToolmakerSteve

BTW, tôi đồng ý với @ CarlosMuñoz về thử nghiệm khi bắt đầu phương thức - phiên bản thử nghiệm của anh ta là phong cách lập trình tốt hơn - return string.Emptyở đây sẽ ẩn một lời gọi "xấu" đối với phương thức.
ToolmakerSteve

46

Bạn có thể sử dụng "phương thức ToTitleCase"

string s = new CultureInfo("en-US").TextInfo.ToTitleCase("red house");
//result : Red House

phương pháp mở rộng này giải quyết mọi vấn đề về Titlecase.

dễ sử dụng

string str = "red house";
str.ToTitleCase();
//result : Red house

string str = "red house";
str.ToTitleCase(TitleCase.All);
//result : Red House

phương pháp mở rộng

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Test
{
    public static class StringHelper
    {
        private static CultureInfo ci = new CultureInfo("en-US");
        //Convert all first latter
        public static string ToTitleCase(this string str)
        {
            str = str.ToLower();
            var strArray = str.Split(' ');
            if (strArray.Length > 1)
            {
                strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                return string.Join(" ", strArray);
            }
            return ci.TextInfo.ToTitleCase(str);
        }
        public static string ToTitleCase(this string str, TitleCase tcase)
        {
            str = str.ToLower();
            switch (tcase)
            {
                case TitleCase.First:
                    var strArray = str.Split(' ');
                    if (strArray.Length > 1)
                    {
                        strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                        return string.Join(" ", strArray);
                    }
                    break;
                case TitleCase.All:
                    return ci.TextInfo.ToTitleCase(str);
                default:
                    break;
            }
            return ci.TextInfo.ToTitleCase(str);
        }
    }

    public enum TitleCase
    {
        First,
        All
    }
}

Vấn đề với giải pháp của bạn là "ngôi nhà đỏ" sẽ được chuyển đổi thành "Nhà đỏ" chứ không phải là "Nhà đỏ" như đã hỏi trong câu hỏi.
Vadim

3
@Tacttin Nó sẽ hoạt động nhưng đoạn mã sau dễ đọc hơn và hoạt động tốt hơn char.ToUpper (text [0]) + ((text.Lipse> 1)? Text.Sub chuỗi (1) .ToLower (): string.Empty) ; Bạn có thể đọc thêm @ vkreynin.wordpress.com/2013/10/09/...
Vadim

1
Tôi không thích giải pháp này, vì nó kết hợp hai tình huống khá khác nhau thành một phương pháp dài. Tôi cũng không thấy một lợi ích khái niệm. Và việc thực hiện viết hoa chỉ chữ cái đầu tiên là .. nực cười. Nếu bạn muốn viết hoa chữ cái đầu tiên, việc thực hiện rõ ràng là chỉ viết hoa (ToUpper) chữ cái đầu tiên . Thay vì điều này, tôi sẽ có hai phương pháp riêng biệt. FirstLetterToUppertrong câu trả lời của Equiso (hoặc trong câu trả lời mới hơn của Guillernet), và ToTitleCaseở đây, nhưng không có tham số thứ hai. Vậy thì không cần enum TitleCase.
ToolmakerSteve

31

Đối với chữ cái đầu tiên, với kiểm tra lỗi:

public string CapitalizeFirstLetter(string s)
{
    if (String.IsNullOrEmpty(s))
        return s;
    if (s.Length == 1)
        return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
}

Và đây là một phần mở rộng tiện dụng

public static string CapitalizeFirstLetter(this string s)
    {
    if (String.IsNullOrEmpty(s)) return s;
    if (s.Length == 1) return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
    }

Cách tiếp cận sạch sẽ. Cảm ơn bạn!
Philippe

11
public static string ToInvarianTitleCase(this string self)
{
    if (string.IsNullOrWhiteSpace(self))
    {
        return self;
    }

    return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(self);
}

6

Nếu việc sử dụng hiệu năng / bộ nhớ là một vấn đề thì cái này chỉ tạo một (1) StringBuilder và một (1) Chuỗi mới có cùng kích thước với chuỗi gốc.

public static string ToUpperFirst(this string str) {
  if( !string.IsNullOrEmpty( str ) ) {
    StringBuilder sb = new StringBuilder(str);
    sb[0] = char.ToUpper(sb[0]);

    return sb.ToString();

  } else return str;
}

3
Điều này có thể được thực hiện với một cách đơn giản char[]hơn là có tất cả các cơ sở hạ tầng của StringBuildernó. Thay vì new StringBuilder(str)sử dụng str.ToCharArray(), và thay vì sb.ToString()sử dụng new string(charArray). StringBuildermô phỏng kiểu lập chỉ mục mà một mảng ký tự hiển thị nguyên bản, do đó, .ToUpperdòng thực tế có thể giống nhau. :-)
Jonathan Gilbert

Darren (một năm sau) cho thấy cách thực hiện việc này bằng cách sử dụng ToCharArray, như được đề xuất bởi @JonathanGilbert
ToolmakerSteve

6

Phương pháp nhanh nhất.

  private string Capitalize(string s){
        if (string.IsNullOrEmpty(s))
        {
            return string.Empty;
        }
        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
}

Các thử nghiệm hiển thị kết quả tiếp theo (chuỗi có 10000000 ký hiệu làm đầu vào): Kết quả thử nghiệm


1
Tôi khuyên bạn nên trả về stham số khi null hoặc rỗng.
MatrixRonny

4

Thử cái này:

static public string UpperCaseFirstCharacter(this string text) {
    return Regex.Replace(text, "^[a-z]", m => m.Value.ToUpper());
}

2
hoặc có lẽ một số lớp ký tự khác (ví dụ như chữ và số \ w), để chức năng này không nhận biết được
Dmitry Ledentsov

@ DmitryLedentsov- Lớp chuỗi C # được xây dựng trên các ký tự UTF-16. Lớp chuỗi "Biểu thị văn bản dưới dạng một chuỗi các đơn vị mã UTF-16."
ToolmakerSteve

4

Nếu bạn chỉ quan tâm đến chữ cái đầu tiên được viết hoa và nó không quan trọng với phần còn lại của chuỗi, bạn chỉ có thể chọn ký tự đầu tiên, đặt chữ hoa và nối nó với phần còn lại của chuỗi mà không có ký tự đầu tiên.

String word ="red house";
word = word[0].ToString().ToUpper() + word.Substring(1, word.length -1);
//result: word = "Red house"

Chúng ta cần chuyển đổi ký tự đầu tiên ToString () vì chúng ta đang đọc nó dưới dạng mảng Char và loại Char không có phương thức ToUpper ().


3

Đây là một cách để làm điều đó như một phương thức mở rộng:

static public string UpperCaseFirstCharacter(this string text)
{
    if (!string.IsNullOrEmpty(text))
    {
        return string.Format(
            "{0}{1}",
            text.Substring(0, 1).ToUpper(),
            text.Substring(1));
    }

    return text;
}

Sau đó có thể được gọi là:

//yields "This is Brian's test.":
"this is Brian's test.".UpperCaseFirstCharacter(); 

Và đây là một số bài kiểm tra đơn vị cho nó:

[Test]
public void UpperCaseFirstCharacter_ZeroLength_ReturnsOriginal()
{
    string orig = "";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual(orig, result);
}

[Test]
public void UpperCaseFirstCharacter_SingleCharacter_ReturnsCapital()
{
    string orig = "c";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual("C", result);
}

[Test]
public void UpperCaseFirstCharacter_StandardInput_CapitalizeOnlyFirstLetter()
{
    string orig = "this is Brian's test.";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual("This is Brian's test.", result);
}

1
string.Formatlà quá mức cần thiết; chỉ cần làm text.Substring(0, 1).ToUpper() + text.Substring(1).
ToolmakerSteve

3

Vì tôi cũng tình cờ làm việc này và đang tìm kiếm bất kỳ ý tưởng nào, đây là giải pháp tôi đã tìm đến. Nó sử dụng LINQ và sẽ có thể viết hoa chữ cái đầu tiên của chuỗi, ngay cả khi lần xuất hiện đầu tiên không phải là chữ cái. Đây là phương pháp mở rộng mà tôi đã kết thúc.

public static string CaptalizeFirstLetter(this string data)
{
    var chars = data.ToCharArray();

    // Find the Index of the first letter
    var charac = data.First(char.IsLetter);
    var i = data.IndexOf(charac);

    // capitalize that letter
    chars[i] = char.ToUpper(chars[i]);

    return new string(chars);
}

Tôi chắc chắn có một cách để tối ưu hóa hoặc dọn dẹp điều này một chút.


3

Tôi đã tìm thấy một cái gì đó ở đây http://www.dotnetperls.com/uppercase-first-letter :

static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
    return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1);
}

có lẽ điều này giúp !!


Làm thế nào đây là một cải tiến so với câu trả lời của Equis 4 năm trước?
ToolmakerSteve

3

Kiểm tra xem chuỗi có phải là null không, sau đó chuyển ký tự đầu tiên thành chữ hoa và phần còn lại của chúng thành chữ thường:

public static string FirstCharToUpper(string str)
{
    return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
}

Cảm ơn bạn về giải pháp nhỏ thay vì vài dòng mã chỉ cho một từ chuỗi!
Imran Faruqi

2

Điều này sẽ làm điều đó mặc dù nó cũng sẽ đảm bảo rằng không có thủ đô sai lầm nào không ở đầu từ.

public string(string s)
{
System.Globalization.CultureInfo c = new System.Globalization.CultureInfo("en-us", false)
System.Globalization.TextInfo t = c.TextInfo;

return t.ToTitleCase(s);
}

2
Cần kiểm tra null strước khi gọi tới ToTitleCase.
Taras Alenin

@ CarlosMuñoz tlhIngan Hol không có vỏ chữ trong kịch bản của nó. :-)
Jonathan Gilbert

2

Dường như có rất nhiều điều phức tạp ở đây khi tất cả những gì bạn cần là:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase if a letter
    /// </summary>
    /// <remarks>Null input returns null</remarks>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrWhiteSpace(s))
            return s;

        return char.ToUpper(s[0]) + s.Substring(1);
    }

Điểm đáng chú ý:

  1. Đây là một phương pháp mở rộng.

  2. Nếu đầu vào là null, trống hoặc khoảng trắng, đầu vào được trả về.

  3. String.IsNullOrWhiteSpace được giới thiệu với .NET Framework 4. Điều này sẽ không hoạt động với các khung cũ hơn.


1
Tôi không thấy đây là một cải tiến về câu trả lời được chấp nhận ban đầu từ bốn năm trước. Trên thực tế, nó không nhất quán (vô hại như vậy, nhưng muộn bốn năm, tôi có tiêu chuẩn cao cho câu trả lời mới có thêm lợi ích): Lợi ích duy nhất của việc sử dụng cái mới IsNullOrWhiteSpacehơn là IsNullOrEmpty, nếu bạn sẽ tìm và thay đổi cái không đầu tiên không gian màu trắng . Nhưng bạn không - bạn luôn luôn hoạt động s[0]. Vì vậy, nó vô nghĩa [cả về ngữ nghĩa và hiệu suất] để sử dụng IsNullOrWhiteSpace.
ToolmakerSteve

... Tại sao việc sử dụng này IsNullOrWhiteSpacegây rắc rối cho tôi, là một người đọc bất cẩn có thể nghĩ rằng "Anh ta đã kiểm tra khoảng trắng, vì vậy đoạn mã sau thực sự tìm và thay đổi một chữ cái, ngay cả khi nó có trước khoảng trắng". Vì mã của bạn sẽ không thay đổi chữ cái "đầu tiên" có trước khoảng trắng, nên việc sử dụng IsNullOrWhiteSpacechỉ có thể đánh lừa người đọc.
ToolmakerSteve

... Rất tiếc, tôi không có nghĩa là câu trả lời được chấp nhận, ý tôi là câu trả lời của Equiso trong cùng khoảng thời gian.
ToolmakerSteve

1
string emp="TENDULKAR";
string output;
output=emp.First().ToString().ToUpper() + String.Join("", emp.Skip(1)).ToLower();

Tại sao ToLower () ở đuôi?. Không có yêu cầu cho các chữ cái khác nhưng cái đầu tiên.
Carlos Muñoz

Stringcó thể là bất cứ điều gì Upperhoặc Lower.so nó là một giải pháp chung cho tất cả các chuỗi.
Shailesh

Tại sao Jointhay vì emp.First().ToString().ToUpper() + emp.Substring(1);? Có lẽ cũng cần phải phòng thủ nhiều hơn : output = string.IsNullOrEmpty(emp) ? string.Empty : [...]. Ngoài ra, fwiw, đồng ý với @ CarlosMuñoz - bạn không cần ToLower()câu hỏi của OP.
ruffin

@ ruffin -> sử dụng Substring cũng là phong cách viết mã tốt, tôi đồng ý giải pháp của bạn để cắt mã nhưng trong trường hợp này viết là một ToLower()thực hành lập trình tốt. stringcó thể là bất cứ điều gì Trong Uppertrường hợp hoặc Lowertrường hợp phụ thuộc vào đầu vào của người dùng, tôi đưa ra một giải pháp chung.
Shailesh

@Shailesh - Tuy nhiên, câu hỏi không yêu cầu chỉ chữ cái đầu tiên là vốn. Nó yêu cầu rằng chữ cái đầu tiên được thay đổi thành một thủ đô. Không cần làm rõ thêm từ tác giả, giả định tự nhiên nhất là phần còn lại của chuỗi không thay đổi. Cho rằng bạn đang trả lời ba năm sau , xin vui lòng giả sử rằng câu trả lời được chấp nhận thực hiện những gì người hỏi yêu cầu. Chỉ đưa ra một câu trả lời khác nhau nếu có một số lý do kỹ thuật để làm điều đó khác đi.
ToolmakerSteve

1

Tôi muốn cung cấp câu trả lời "HIỆU SUẤT TỐI ĐA". Trong tâm trí của tôi, một câu trả lời "HIỆU SUẤT TỐI ĐA" nắm bắt tất cả các kịch bản và cung cấp câu trả lời cho kế toán câu hỏi cho các kịch bản đó. Vì vậy, đây là câu trả lời của tôi. Với những lý do sau:

  1. Tài khoản IsNullOrWhiteSpace cho các chuỗi chỉ là khoảng trắng hoặc null / trống.
  2. .Trim () xóa khoảng trắng từ mặt trước và mặt sau của chuỗi.
  3. .First () lấy ký tự đầu tiên của một ienumerable (hoặc chuỗi).
  4. Chúng ta nên kiểm tra xem đó có phải là chữ cái có thể / nên viết hoa không.
  5. Sau đó chúng ta thêm phần còn lại của chuỗi, chỉ khi độ dài cho biết chúng ta nên.
  6. Bằng cách thực hành tốt nhất .Net, chúng tôi sẽ cung cấp một nền văn hóa trong System.Globalization.CARMInfo.
  7. Việc cung cấp cho họ dưới dạng tham số tùy chọn làm cho phương thức này hoàn toàn có thể sử dụng lại mà không phải gõ văn hóa đã chọn mỗi lần.

    public static string capString(string instring, string culture = "en-US", bool useSystem = false)
    {
        string outstring;
        if (String.IsNullOrWhiteSpace(instring))
        {
            return "";
        }
        instring = instring.Trim();
        char thisletter = instring.First();
        if (!char.IsLetter(thisletter))
        {
            return instring;   
        }
        outstring = thisletter.ToString().ToUpper(new CultureInfo(culture, useSystem));
        if (instring.Length > 1)
        {
            outstring += instring.Substring(1);
        }
        return outstring;
    }

2
Trong khi điều này bao gồm hầu hết các trường hợp, nó sẽ khá chậm khi xem xét số lượng chuỗi được tạo với mỗi thao tác? Có một tấn phân bổ chuỗi đang diễn ra ở đây. Tốt nhất là nó sẽ được phân bổ một lần, và chỉ một lần.
Douglas Gaskell

1

Gần đây tôi có một yêu cầu tương tự và nhớ rằng hàm LINQ Chọn () cung cấp một chỉ mục:

string input;
string output;

input = "red house";
output = String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
//output = "Red house"

Vì tôi rất cần điều đó nên tôi đã tạo một phương thức mở rộng cho kiểu chuỗi:

public static class StringExtensions
{
    public static string FirstLetterToUpper(this string input)
    {
        if (string.IsNullOrEmpty(input))
            return string.Empty;
        return String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
    }
}

Xin lưu ý rằng chỉ chữ cái đầu tiên được chuyển thành chữ hoa - tất cả các ký tự còn lại không được chạm vào. Nếu bạn cần các ký tự khác viết thường, bạn cũng có thể gọi Char.ToLower (currentChar) cho chỉ mục> 0 hoặc gọi ToLower () trên toàn bộ chuỗi ở vị trí đầu tiên.

Về hiệu suất tôi đã so sánh mã với giải pháp từ Darren. Trên máy của tôi, mã của Darren nhanh hơn khoảng 2 lần, điều này không có gì đáng ngạc nhiên vì anh ta chỉ chỉnh sửa trực tiếp chữ cái đầu tiên trong một mảng char. Vì vậy, tôi khuyên bạn nên lấy mã của Darren nếu bạn cần giải pháp nhanh nhất hiện có. Nếu bạn muốn tích hợp các thao tác chuỗi khác cũng có thể thuận tiện khi có sức mạnh biểu cảm của hàm lambda chạm vào các ký tự của chuỗi đầu vào - bạn có thể dễ dàng mở rộng chức năng này - vì vậy tôi để giải pháp này ở đây.


Tôi đã tự hỏi làm thế nào tôi sẽ giải quyết vấn đề này, tìm ra giải pháp của riêng tôi, sau đó quay lại để đăng nó chỉ để thấy bạn đã đưa ra giải pháp chính xác như tôi đã có. +1 cho bạn!
BlueFuzzyThời gian

Cảm ơn rât nhiều.
Grimm

1

Tôi nghĩ rằng phương pháp dưới đây là giải pháp tốt nhất

    class Program
{
    static string UppercaseWords(string value)
    {
        char[] array = value.ToCharArray();
        // Handle the first letter in the string.
        if (array.Length >= 1)
        {
            if (char.IsLower(array[0]))
            {
                array[0] = char.ToUpper(array[0]);
            }
        }
        // Scan through the letters, checking for spaces.
        // ... Uppercase the lowercase letters following spaces.
        for (int i = 1; i < array.Length; i++)
        {
            if (array[i - 1] == ' ')
            {
                if (char.IsLower(array[i]))
                {
                    array[i] = char.ToUpper(array[i]);
                }
            }
        }
        return new string(array);
    }

    static void Main()
    {
        // Uppercase words in these strings.
        const string value1 = "something in the way";
        const string value2 = "dot net PERLS";
        const string value3 = "String_two;three";
        const string value4 = " sam";
        // ... Compute the uppercase strings.
        Console.WriteLine(UppercaseWords(value1));
        Console.WriteLine(UppercaseWords(value2));
        Console.WriteLine(UppercaseWords(value3));
        Console.WriteLine(UppercaseWords(value4));
    }
}

Output

Something In The Way
Dot Net PERLS
String_two;three
 Sam

tham chiếu


1

Vì câu hỏi này là về tối đa hóa hiệu suất, tôi đã sử dụng phiên bản của Darren để sử dụng Spans, giúp giảm rác và cải thiện tốc độ khoảng 10%.

        /// <summary>
        /// Returns the input string with the first character converted to uppercase
        /// </summary>
        public static string ToUpperFirst(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }

Hiệu suất

|  Method |      Data |      Mean |     Error |    StdDev |
|-------- |---------- |----------:|----------:|----------:|
|  Carlos |       red | 107.29 ns | 2.2401 ns | 3.9234 ns |
|  Darren |       red |  30.93 ns | 0.9228 ns | 0.8632 ns |
| Marcell |       red |  26.99 ns | 0.3902 ns | 0.3459 ns |
|  Carlos | red house | 106.78 ns | 1.9713 ns | 1.8439 ns |
|  Darren | red house |  32.49 ns | 0.4253 ns | 0.3978 ns |
| Marcell | red house |  27.37 ns | 0.3888 ns | 0.3637 ns |

Mã kiểm tra đầy đủ

using System;
using System.Linq;

using BenchmarkDotNet.Attributes;

namespace CorePerformanceTest
{
    public class StringUpperTest
    {
        [Params("red", "red house")]
        public string Data;

        [Benchmark]
        public string Carlos() => Data.Carlos();

        [Benchmark]
        public string Darren() => Data.Darren();

        [Benchmark]
        public string Marcell() => Data.Marcell();
    }

    internal static class StringExtensions
    {
        public static string Carlos(this string input) =>
            input switch
            {
                null => throw new ArgumentNullException(nameof(input)),
                "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
                _ => input.First().ToString().ToUpper() + input.Substring(1)
            };

        public static string Darren(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            char[] a = s.ToCharArray();
            a[0] = char.ToUpper(a[0]);
            return new string(a);
        }

        public static string Marcell(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }
    }

}

Chỉnh sửa: Có một loại, thay vì s [0], là [0] - kết quả này với giá trị cupying giống nhau, trống cho Span được phân bổ a.


0

Chữ này viết hoa chữ cái đầu tiên này và mỗi chữ cái theo sau một khoảng trắng và chữ thường bất kỳ chữ cái nào khác.

public string CapitalizeFirstLetterAfterSpace(string input)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder(input);
    bool capitalizeNextLetter = true;
    for(int pos = 0; pos < sb.Length; pos++)
    {
        if(capitalizeNextLetter)
        {
            sb[pos]=System.Char.ToUpper(sb[pos]);
            capitalizeNextLetter = false;
        }
        else
        {
            sb[pos]=System.Char.ToLower(sb[pos]);
        }

        if(sb[pos]=' ')
        {
            capitalizeNextLetter=true;
        }
    }
}

1
Hoặc nếu bạn không muốn viết các bức tường mã - CultureInfo.CiverseCARM.TextInfo.ToTitleCase (theString); làm điều tương tự
Chev

Vâng ... tôi không biết về điều đó :) Và do số lượng mã lớn của tôi, câu trả lời của mọi người khác xuất hiện trong khi tôi vẫn đang gõ.
thattcarguy

UPVOTED: 1) Một sự khác biệt nhỏ giữa câu trả lời này và ToTitleCase, là câu trả lời này buộc các từ có tất cả các chữ hoa trở thành TitleCase, trong khi ToTitleCase chỉ để lại những từ như vậy (giả sử chúng có thể là từ viết tắt). Điều này có thể hoặc không thể là những gì mong muốn. Một lợi thế của việc có một ví dụ mã như thế này, là nó có thể được sửa đổi theo ý muốn. 2) điều này sẽ không xử lý khoảng trắng ngoài '' chính xác. nên thay thế kiểm tra trống bằng kiểm tra không gian trắng.
ToolmakerSteve

0

Sử dụng mã sau đây:

string  strtest ="PRASHANT";
strtest.First().ToString().ToUpper() + strtest.Remove(0, 1).ToLower();

Nó thậm chí không có giá trị đối với đại diện của tôi để hạ thấp câu trả lời này được thêm vào nhiều năm sau đó, điều đó rõ ràng tương đương với câu trả lời đã có sẵn. Nếu bạn định thêm một câu trả lời mới cho một câu hỏi có nhiều câu trả lời, vui lòng giải thích những gì bạn tin là vượt trội về câu trả lời của bạn hoặc trong trường hợp nào câu trả lời của bạn sẽ hữu ích hơn các câu trả lời khác. Hãy cụ thể.
ToolmakerSteve

0

Có vẻ như không có giải pháp nào được đưa ra ở đây sẽ xử lý một khoảng trắng trước chuỗi.

Chỉ cần thêm điều này như một suy nghĩ:

public static string SetFirstCharUpper2(string aValue, bool aIgonreLeadingSpaces = true)
{
    if (string.IsNullOrWhiteSpace(aValue))
        return aValue;

    string trimmed = aIgonreLeadingSpaces 
           ? aValue.TrimStart() 
           : aValue;

    return char.ToUpper(trimmed[0]) + trimmed.Substring(1);
}   

Nó sẽ xử lý this won't work on other answers(câu đó có khoảng trắng ở đầu) và nếu bạn không thích cắt xén không gian, chỉ cần chuyển falsetham số thứ hai (hoặc thay đổi mặc định thành falsevà chuyển truenếu bạn muốn xử lý khoảng trắng)



0

Cách dễ nhất để viết hoa chữ cái linh sam là:

1- Sử dụng Sytem.Globalization;

  // Creates a TextInfo based on the "en-US" culture.
  TextInfo myTI = new CultureInfo("en-US",false).

  myTI.ToTitleCase(textboxname.Text)

`


1
Câu trả lời này về cơ bản giống với câu trả lời được đưa ra nhiều năm trước đó. Nó không thêm gì để thảo luận.
ToolmakerSteve

Nó cũng sai, giống như nhận xét trong một bình luận khác, điều này biến mọi chữ cái đầu tiên trong tất cả các từ vốn không phải là Red House thay vì Red house.
DeadlyChambers

0

chức năng sau đây là chính xác cho tất cả các cách:

static string UppercaseWords(string value)
{
    char[] array = value.ToCharArray();
    // Handle the first letter in the string.
    if (array.Length >= 1)
    {
        if (char.IsLower(array[0]))
        {
            array[0] = char.ToUpper(array[0]);
        }
    }
    // Scan through the letters, checking for spaces.
    // ... Uppercase the lowercase letters following spaces.
    for (int i = 1; i < array.Length; i++)
    {
        if (array[i - 1] == ' ')
        {
            if (char.IsLower(array[i]))
            {
                array[i] = char.ToUpper(array[i]);
            }
        }
    }
    return new string(array);
}

Tôi thấy rằng ở đây


Tại sao? Tại sao thêm một câu trả lời khác khi đã có rất nhiều câu trả lời có vẻ giống nhau? Có gì sai với tất cả các câu trả lời hiện có, điều đó thôi thúc bạn thêm một câu trả lời khác?
ToolmakerSteve

Bởi vì phần mềm này là chính xác cho tất cả các cách. Bình tĩnh nào

Tôi xin lỗi; Tôi đã khắc nghiệt không cần thiết. Tôi sẽ bám sát sự thật: 1) Điều này về cơ bản giống như câu trả lời của thattcarguy bảy năm trước. 2) Điều này có cùng một lỗ hổng với câu trả lời: không xử lý khoảng trắng ngoài ký tự trống. 3) Điều này trả lời một câu hỏi hơi khác so với OP đã hỏi. Sử dụng một câu trả lời như thế này nếu bạn muốn tất cả các từ được viết hoa chữ cái đầu tiên. 4) Thông thường, cách đơn giản hơn để thực hiện đó là sử dụng TitleInfo.ToTitleCase. (Mặt khác, một lợi thế của mẫu mã có thể tùy chỉnh theo ý muốn.)
ToolmakerSteve

Sửa lỗi cho bản thân: Điều này khác với cách tiếp cận của thattcarguy: nó để lại những chữ cái chưa được xử lý không phải là chữ cái đầu tiên của từ này. Thay vào đó, nó là một bản sao của câu trả lời của zamoldar . Một cách thuận lợi, danh tiếng cho Darian vì đã đưa liên kết đến nguồn - có vẻ như zamoldar đạo văn mà không cung cấp tín dụng. Vì cung cấp liên kết nguồn đó và do đó cải thiện cuộc thảo luận , tôi ủng hộ câu trả lời này, bất chấp những lời chỉ trích của tôi về nó.
ToolmakerSteve

1
Darian, hai cải tiến có thể được thực hiện: 1) sử dụng char.IsWhiteSpace( array[ i -1 ] )thay vì .. == ' ', để xử lý tất cả khoảng trắng. 2) loại bỏ hai nơi làm if (char.isLower(..))- chúng không phục vụ mục đích. ToUpperchỉ đơn giản là không làm gì nếu một nhân vật không phải là chữ thường.
ToolmakerSteve

0

Mở rộng câu hỏi của Carlos ở trên, nếu bạn muốn viết hoa nhiều câu, bạn có thể sử dụng mã này:

    /// <summary>
    /// Capitalize first letter of every sentence. 
    /// </summary>
    /// <param name="inputSting"></param>
    /// <returns></returns>
    public string CapitalizeSentences (string inputSting)
    {
        string result = string.Empty;
        if (!string.IsNullOrEmpty(inputSting))
        {
            string[] sentences = inputSting.Split('.');

            foreach (string sentence in sentences)
            {
                result += string.Format ("{0}{1}.", sentence.First().ToString().ToUpper(), sentence.Substring(1)); 
            }
        }

        return result; 
    }

0

Giải pháp có thể để giải quyết vấn đề của bạn.

   public static string FirstToUpper(this string lowerWord)
   {
       if (string.IsNullOrWhiteSpace(lowerWord) || string.IsNullOrEmpty(lowerWord))
            return lowerWord;
       return new StringBuilder(lowerWord.Substring(0, 1).ToUpper())
                 .Append(lowerWord.Substring(1))
                 .ToString();
   }
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 cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.