[C#] .NET 문자열을 자르려면 어떻게합니까?

길이가 주어진 값보다 길지 않도록 문자열을 자르고 싶습니다. 데이터베이스 테이블에 쓰고 있는데 작성하는 값이 열 데이터 유형의 제약 조건을 충족하는지 확인하고 싶습니다.

예를 들어, 다음을 쓸 수 있다면 좋을 것입니다.

string NormalizeLength(string value, int maxLength)
{
    return value.Substring(0, maxLength);
}

불행히도 maxLength일반적으로 문자열의 경계를 초과 하기 때문에 예외가 발생 합니다 value. 물론 다음과 같은 함수를 작성할 수는 있지만 이와 같은 것이 이미 존재하기를 희망했습니다.

string NormalizeLength(string value, int maxLength)
{
    return value.Length <= maxLength ? value : value.Substring(0, maxLength);
} 

이 작업을 수행하는 어려운 API는 어디에 있습니까? 하나 있습니까?



답변

Truncate()불행히도 문자열 에는 메소드 가 없습니다 . 이런 종류의 논리를 직접 작성해야합니다. 그러나 당신이 할 수있는 일은 이것을 확장 방법으로 감싸서 어디에서나 복제 할 필요가 없습니다.

public static class StringExt
{
    public static string Truncate(this string value, int maxLength)
    {
        if (string.IsNullOrEmpty(value)) return value;
        return value.Length <= maxLength ? value : value.Substring(0, maxLength);
    }
}

이제 다음과 같이 쓸 수 있습니다 :

var someString = "...";
someString = someString.Truncate(2);


답변

또는 삼항 연산자 대신 Math.min을 사용할 수 있습니다.

public static class StringExt
{
    public static string Truncate( this string value, int maxLength )
    {
        if (string.IsNullOrEmpty(value)) { return value; }

        return value.Substring(0, Math.Min(value.Length, maxLength));
    }
}


답변

나는 그것이 다른 사람들에 의해 접촉 된 모든 사례를 다루고 여전히 읽을 수있는 간결한 방식으로 그렇게한다고 믿기 때문에 구현을 포기할 것이라고 생각했다.

public static string Truncate(this string value, int maxLength)
{
    if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
    {
        return value.Substring(0, maxLength);
    }

    return value;
}

이 솔루션은 주로 Ray의 솔루션을 하며 LBushkin이 솔루션에서 수행하는 것처럼 this 키워드 를 사용하여 확장 방법으로 사용할 방법을 엽니 다 .


답변

성능 테스트가 재미 있기 때문에 : ( linqpad 확장 방법 사용 )

var val = string.Concat(Enumerable.Range(0, 50).Select(i => i % 10));

foreach(var limit in new[] { 10, 25, 44, 64 })
    new Perf<string> {
        { "newstring" + limit, n => new string(val.Take(limit).ToArray()) },
        { "concat" + limit, n => string.Concat(val.Take(limit)) },
        { "truncate" + limit, n => val.Substring(0, Math.Min(val.Length, limit)) },
        { "smart-trunc" + limit, n => val.Length <= limit ? val : val.Substring(0, limit) },
        { "stringbuilder" + limit, n => new StringBuilder(val, 0, Math.Min(val.Length, limit), limit).ToString() },
    }.Vs();

truncate방법은 “상당히”빨랐습니다. # 미세 최적화

이른

  • truncate10 5788 틱 경과 (0.5788ms) [10K 반복, 5.788E-05ms 당]
  • smart-trunc10 8206 틱 경과 (0.8206ms) [10K 반복, 8.206E-05ms / 초]
  • stringbuilder10 10557 틱 경과 (1.0557ms) [10K 반복, 0.00010557ms 당]
  • concat10 45495 틱 경과 (4.5495ms) [10K 반복, 0.00045495ms 당]
  • newstring10 72535 틱 경과 (7.2535ms) [10K 반복, 0.00072535ms]

늦은

  • truncate44 8835 틱 경과 (0.8835ms) [10K 반복, 8.835E-05ms 당]
  • stringbuilder44 13106 틱 경과 (1.3106ms) [10K 반복, 0.00013106ms 당]
  • smart-trunc44 14821 틱 경과 (1.4821ms) [10K 반복, 0.00014821ms 당]
  • newstring44 144324 틱 경과 (14.4324ms) [10K 반복, 0.00144324ms 당]
  • concat44 174610 틱 경과 (17.461ms) [10K 반복, 0.0017461ms / 초]

너무 오래

  • smart-trunc64 6944 틱 경과 (0.6944ms) [10K 반복, 6.944E-05ms 당]
  • truncate64 7686 틱 경과 (0.7686ms) [10K 반복, 7.686E-05ms 당]
  • stringbuilder64 13314 틱 경과 (1.3314ms) [10K 반복, 0.00013314ms 당]
  • newstring64 177481 틱 경과 (17.7481ms) [10K 반복, 0.00177481ms 당]
  • concat64 241601 틱 경과 (24.1601ms) [10K 반복, 0.00241601ms 당]

답변

.NET 4.0에서는 다음 Take방법을 사용할 수 있습니다 .

string.Concat(myString.Take(maxLength));

효율성을 테스트하지 않았습니다!


답변

LINQ를 사용할 수 있습니다 … 문자열 길이를 확인할 필요가 없습니다. 아마도 가장 효율적이지는 않지만 재미 있습니다.

string result = string.Join("", value.Take(maxLength)); // .NET 4 Join

또는

string result = new string(value.Take(maxLength).ToArray());


답변

나는 이런 식으로 한 줄로 내 것을 했어

value = value.Length > 1000 ? value.Substring(0, 1000) : value;