文字列が長すぎる場合、どうすれば文字列を「…」で切り捨てることができますか?


84

誰かが良い考えを持っていることを願っています。私はこのような文字列を持っています:

abcdefg
abcde
abc

私が必要としているのは、指定された長さを超える場合に、次のように表示されるように調整することです。

abc ..
abc ..
abc

これに使用できる簡単なC#コードはありますか?


どこでこれをしたいですか?--FormsまたはWPFアプリまたはWebサイトで-詳細を入力してください!
バリーケイ2011

2
ほとんどのソリューションの問題は、Char制限としてsの数を使用することです。残念ながら、グラフィックの幅は大きく異なる可能性があります。そして、UTF-16サロゲート、結合文字、...がある
CodesInChaos

12
これは提案された質問の複製ではありません。これは非常に一般的な質問ですが、提案された重複は非常に具体的な質問です。
JasonMArcher 2011

2
これは、提案された質問の複製ではありません。
セス

2
この質問は、提案された重複にさえ近くありません。重複属性を削除してください。どうも。
Daniel Leiszen 2016年

回答:


146

拡張メソッドにまとめられたロジックは次のとおりです。

public static string Truncate(this string value, int maxChars)
{
    return value.Length <= maxChars ? value : value.Substring(0, maxChars) + "...";
}

使用法:

var s = "abcdefg";

Console.WriteLine(s.Truncate(3));

1
ブライアンありがとう。あなたの答えはよさそうだ。私の簡単な質問を許してください、しかし私はどのように拡張メソッドを使うのですか?
メロニー2011

1
@Melony:使用法を含めるように編集されました。
ブライアンワッツ

11
…(省略記号)は、気になる人にとって正しい記号です。Unicode U +2026。
マラコ2017

3
ヌルチェックを含めるためのクイック追加
ジェームズ2018年

1
ありがとう@ Malako–: value.Substring(0, maxChars) + (char)0x2026;
ピエール

8
public string TruncString(string myStr, int THRESHOLD)
{
    if (myStr.Length > THRESHOLD)
        return myStr.Substring(0, THRESHOLD) + "...";
    return myStr;
}

彼が実際にTHRESHOLD変数を必要とする場合、または常に同じサイズである場合に備えて、命名規則を無視してください。

あるいは

string res = (myStr.Length > THRESHOLD) ? myStr.Substring(0, THRESHOLD) + ".." : myStr;

これを1行でインラインで使用できるものにすることはできますか?
メロニー2011

2
コードポイントを途中で分割すると、無効な文字列が生成される可能性があります:(
CodesInChaos 2011

7

すべて非常に良い答えですが、少しだけクリーンアップするために、文字列が文である場合は、単語の途中で文字列を壊さないでください。

private string TruncateForDisplay(this string value, int length)
{
  if (string.IsNullOrEmpty(value)) return string.Empty;
  var returnValue = value;
  if (value.Length > length)
  {
    var tmp = value.Substring(0, length) ;
    if (tmp.LastIndexOf(' ') > 0)
       returnValue = tmp.Substring(0, tmp.LastIndexOf(' ') ) + " ...";
  }                
  return returnValue;
}

これは言葉を壊さない唯一の答えです。したがって、唯一の正しいIMOです。
mxmissile

@ mxmissile-OPデータを指定すると、「abcdefg」の場合、3文字で切り捨てられ、「abc ...」に移動します。これが機能したとしても、まったく正しくありません。OPサンプルデータは、連続するテキストの途中でハードトランケートが行われていることを明確に示しています。さらに悪いことに、この答えはエラーを生成します。データにスペースが含まれていないため、はLastIndexOf-1を返し、Substringはランタイムエラーを引き起こします。

4

楕円の長さを考慮したバージョンは次のとおりです。

    public static string Truncate(this string value, int maxChars)
    {
        const string ellipses = "...";
        return value.Length <= maxChars ? value : value.Substring(0, maxChars - ellipses.Length) + ellipses;
    }

4
省略記号を使用する場合は、その必要はありません。文字の長さは常に1になりますconst char ellipse = (char)0x2026;
ピエール

3

これを行う.NETFrameworkには組み込みのメソッドはありませんが、これは自分で作成する非常に簡単なメソッドです。手順は次のとおりです。自分で作成してみて、思いついたことをお知らせください。

  1. メソッド、おそらく拡張メソッドを作成します public static void TruncateWithEllipsis(this string value, int maxLength)

  2. 渡された値がmaxLengthLengthプロパティを使用して指定された値より大きいかどうかを確認します。場合valueよりも大きくないmaxLength、ただ返しますvalue

  3. 渡された値をそのまま返さなかった場合は、切り捨てる必要があることがわかります。したがって、SubStringメソッドを使用して文字列のより小さなセクションを取得する必要があります。このメソッドは、指定された開始値と終了値に基づいて、文字列のより小さなセクションを返します。終了位置はmaxLengthパラメータによって渡されたものなので、それを使用します。

  4. 文字列のサブセクションと省略記号を返します。

後で行うための優れた演習は、メソッドを更新し、完全な単語の後でのみメソッドを中断させることです。オーバーロードを作成して、文字列が切り捨てられたことをどのように表示するかを指定することもできます。たとえば、アプリケーションがクリックして詳細を表示するように設定されている場合、メソッドは「...」ではなく「(クリックして詳細)」を返すことができます。


2

背後にあるコード:

string shorten(sting s)
{
    //string s = abcdefg;
    int tooLongInt = 3;

    if (s.Length > tooLongInt)
        return s.Substring(0, tooLongInt) + "..";

    return s;
}

マークアップ:

<td><%= shorten(YOUR_STRING_HERE) %></td>

これをどのように当てはめることができますか: "<td>" + string + "<\ td>"?
メロニー2011

2

たぶん、その目的のためにメソッドを実装する方が良いでしょう:

string shorten(sting yourStr)
{
//Suppose you have a string yourStr, toView and a constant value 

    string toView;
    const int maxView = 3;

    if (yourStr.Length > maxView)
        toView = yourStr.Substring(0, maxView) + " ..."; // all you have is to use Substring(int, int) .net method
    else
        toView = yourStr;
return toView;
}

1
string s = "abcdefg";
if (s.length > 3)
{
    s = s.substring(0,3);
}

Substring関数を使用できます。


1

「C#truncate ellipsis」を検索したところ、この質問が見つかりました。さまざまな回答を使用して、次の機能を備えた独自のソリューションを作成しました。

  1. 拡張メソッド
  2. 省略記号を追加します
  3. 省略記号をオプションにします
  4. 文字列を切り捨てる前に、文字列がnullまたは空でないことを確認してください。

    public static class StringExtensions
    {
        public static string Truncate(this string value, 
            int maxLength, 
            bool addEllipsis = false)
        {
            // Check for valid string before attempting to truncate
            if (string.IsNullOrEmpty(value)) return value;
    
            // Proceed with truncating
            var result = string.Empty;
            if (value.Length > maxLength)
            {
                result = value.Substring(0, maxLength);
                if (addEllipsis) result += "...";
            }
            else
            {
                result = value;
            }
    
            return result;
        }
    }
    

これが他の誰かに役立つことを願っています。


0

確かに、ここにいくつかのサンプルコードがあります:

string str = "abcdefg";
if (str.Length > X){
   str = str.Substring(0, X) + "...";
}

0

私は最近この問題を抱えています。4000文字のnvarcharMAXDBフィールドに「ステータス」メッセージを保存していました。しかし、私のステータスメッセージは蓄積され、例外にぶつかっていました。

しかし、任意の切り捨てによってステータスメッセージの一部が孤立するため、単純な切り捨てのケースではありませんでした。そのため、文字列の一貫した部分で「切り捨て」る必要がありました。

文字列を文字列配列に変換し、最初の要素を削除してから文字列に復元することで、問題を解決しました。これがコードです( "CurrentStatus"はデータを保持する文字列です)...

        if (CurrentStatus.Length >= 3750)
        {
            // perform some truncation to free up some space.

            // Lets get the status messages into an array for processing...
            // We use the period as the delimiter, then skip the first item and re-insert into an array.

            string[] statusArray = CurrentStatus.Split(new string[] { "." }, StringSplitOptions.None)
                                    .Skip(1).ToArray();

            // Next we return the data to a string and replace any escaped returns with proper one.
            CurrentStatus = (string.Join(".", statusArray))
                                    .Replace("\\r\\n", Environment.NewLine);


        }

それが誰かを助けることを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.