7

我有一根很长的绳子,我想把它放在一个小地方。为了实现这一点,我将字符串分成空格上的行。算法是这样的:

    public static string BreakLine(string text, int maxCharsInLine)
    {
        int charsInLine = 0;
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < text.Length; i++)
        {
            char c = text[i];
            builder.Append(c);
            charsInLine++;

            if (charsInLine >= maxCharsInLine && char.IsWhiteSpace(c))
            {
                builder.AppendLine();
                charsInLine = 0;
            }
        }
        return builder.ToString();
    }

但是当有一个短词,然后是一个较长的词时,这就会中断。最大长度为 16 的“foo howcomputerwork”不会中断,但我想要它。一个想法是我期待看到下一个空格出现在哪里,但我不确定这是否会导致尽可能少的行。

4

3 回答 3

6

享受!

public static string SplitToLines(string text, char[] splitOnCharacters, int maxStringLength)
{
    var sb = new StringBuilder();
    var index = 0;

    while (text.Length > index)
    {
        // start a new line, unless we've just started
        if (index != 0)
            sb.AppendLine();

        // get the next substring, else the rest of the string if remainder is shorter than `maxStringLength`
        var splitAt = index + maxStringLength <= text.Length
            ? text.Substring(index, maxStringLength).LastIndexOfAny(splitOnCharacters)
            : text.Length - index;

        // if can't find split location, take `maxStringLength` characters
        splitAt = (splitAt == -1) ? maxStringLength : splitAt;

        // add result to collection & increment index
        sb.Append(text.Substring(index, splitAt).Trim());
        index += splitAt;
    }

    return sb.ToString();
}

请注意,splitOnCharacters并且maxStringLength可以保存在应用程序的用户设置区域中。

于 2014-09-10T13:42:50.363 回答
1

在写入字符串生成器之前检查字符的内容,并or使用当前计数:

    public static string BreakLine(string text, int maxCharsInLine)
    {
        int charsInLine = 0;
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < text.Length; i++)
        {
            char c = text[i];
            if (char.IsWhiteSpace(c) || charsInLine >= maxCharsInLine)
            {
                builder.AppendLine();
                charsInLine = 0;
            }
            else 
            {
                builder.Append(c);
                charsInLine++;                    
            }
        }
        return builder.ToString();
    }
于 2013-03-08T21:04:19.523 回答
1

稍微更新一下代码,@dead.rabit 有时会进入循环。

 public static string SplitToLines(string text,char[] splitanyOf, int maxStringLength)
    {               
        var sb = new System.Text.StringBuilder();
        var index = 0;
        var loop = 0;
        while (text.Length > index)
        {
            // start a new line, unless we've just started
            if (loop != 0)
            {
                sb.AppendLine();
            }

            // get the next substring, else the rest of the string if remainder is shorter than `maxStringLength`
            var splitAt = 0;
            if (index + maxStringLength <= text.Length)
            {
                splitAt = text.Substring(index, maxStringLength).LastIndexOfAny(splitanyOf);
            }
            else
            {
                splitAt = text.Length - index;
            }

            // if can't find split location, take `maxStringLength` characters
            if (splitAt == -1 || splitAt == 0)
            {
                splitAt = text.IndexOfAny(splitanyOf, maxStringLength);
            }

            // add result to collection & increment index
            sb.Append(text.Substring(index, splitAt).Trim());
            if(text.Length > splitAt)
            {
                text = text.Substring(splitAt + 1).Trim();
            }
            else
            {
                text = string.Empty;
            }
            loop = loop + 1;
        }

        return sb.ToString();
    }
于 2017-02-09T08:09:59.223 回答