繁体   English   中英

将长字符串分成60个字符的长行,但不要破坏单词

[英]Divide long string into 60 character long lines but don't break words

必须有更好的方法来做到这一点。 我只想将长字符串分成60个字符行,但不要破坏单词。 所以它不必添加多达60个字符,只需要小于60。

下面的代码是我所拥有的并且它有效,但我认为有更好的方法。 任何人?

修改为使用StringBuilder并修复了删除重复单词的问题。 也不想使用正则表达式,因为我认为这将比我现在的效率低。

public static List<String> FormatMe(String Message)
{
    Int32 MAX_WIDTH = 60;
    List<String> Line = new List<String>();
    String[] Words;

    Message = Message.Trim();
    Words = Message.Split(" ".ToCharArray());

    StringBuilder s = new StringBuilder();
    foreach (String Word in Words)
    {
        s.Append(Word + " ");
        if (s.Length > MAX_WIDTH)
        {
            s.Replace(Word, "", 0, s.Length - Word.Length);
            Line.Add(s.ToString().Trim());
            s = new StringBuilder(Word + " ");
        }
    }

    if (s.Length > 0)
        Line.Add(s.ToString().Trim());

    return Line;
}

谢谢

另一个(现在是TESTED)样本,与Keith方法非常相似:

static void Main(string[] args)
{
    const Int32 MAX_WIDTH = 60;

    int offset = 0;
    string text = Regex.Replace(File.ReadAllText("oneline.txt"), @"\s{2,}", " ");
    List<string> lines = new List<string>();
    while (offset < text.Length)
    {
        int index = text.LastIndexOf(" ", 
                         Math.Min(text.Length, offset + MAX_WIDTH));
        string line = text.Substring(offset,
            (index - offset <= 0 ? text.Length : index) - offset );
        offset += line.Length + 1;
        lines.Add(line);
    }
}

我在这个文件上运行它,所有换行符都用“”替换。

在正则表达式中,Match Evaluator函数(匿名方法)执行grunt工作并将新大小的行存储到StringBuilder中。 我们不使用Regex.Replace方法的返回值,因为我们只是使用它的Match Evaluator函数作为一个功能来完成正则表达式调用内部的换行 - 只是为了它,因为我觉得它很酷。

using System;
using System.Text;
using System.Text.RegularExpressions;

strInput是你想要转换的行。

int MAX_LEN = 60;
StringBuilder sb = new StringBuilder();
int bmark = 0; //bookmark position

Regex.Replace(strInput, @".*?\b\w+\b.*?", 
    delegate(Match m) {
        if (m.Index - bmark + m.Length + m.NextMatch().Length > MAX_LEN 
                || m.Index == bmark && m.Length >= MAX_LEN) {
            sb.Append(strInput.Substring(bmark, m.Index - bmark + m.Length).Trim() + Environment.NewLine);
            bmark = m.Index + m.Length;
        } return null;
    }, RegexOptions.Singleline);

if (bmark != strInput.Length) // last portion
    sb.Append(strInput.Substring(bmark));

string strModified = sb.ToString(); // get the real string from builder

还有值得注意的是匹配评估m.Index == bmark && m.Length >= MAX_LEN中的if表达式中的第二个条件m.Index == bmark && m.Length >= MAX_LEN是一个异常条件,以防有一个字长于60个字符(或长于该字符集)最大长度) - 它不会在这里分解,而只是单独存储在一行上 - 我猜你可能想在现实世界中为该条件创建第二个公式以连接它或其他东西。

试试这个:

const Int32 MAX_WIDTH = 60;

string text = "...";
List<string> lines = new List<string>();
StringBuilder line = new StringBuilder();
foreach(Match word in Regex.Matches(text, @"\S+", RegexOptions.ECMAScript))
{
    if (word.Value.Length + line.Length + 1 > MAX_WIDTH)
    {
        lines.Add(line.ToString());
        line.Length = 0;
    }
    line.Append(String.Format("{0} ", word.Value));
}

if (line.Length > 0)
    line.Append(word.Value);

请检查一下: 如何使用正则表达式添加换行符?

我首先要保存原始字符串的长度。 然后,向后开始,然后减去,因为可能性是因为从最后一个词开始然后回来而不是累积,我会更快地降到60以下。

一旦我知道了多长时间,那么只需使用StringBuilder并为新字符串构建字符串。

List<string> lines = new List<string>();
while (message.Length > 60) {
  int idx = message.LastIndexOf(' ', 60);
  lines.Add(message.Substring(0, idx));
  message = message.Substring(idx + 1, message.Length - (idx + 1));
}
lines.Add(message);

您可能需要修改一个位来处理多个空格,其中包含> 60个字符的单词,...

我尝试了原始解决方案,发现它不太有效。 我稍微修改了它以使其工作。 它现在适用于我并解决了我遇到的问题。 谢谢。 吉姆。

public static List<String> FormatMe(String message)
    {
        int maxLength = 10;
        List<String> Line = new List<String>();
        String[] words;

        message = message.Trim();
        words = message.Split(" ".ToCharArray());

        StringBuilder sentence = new StringBuilder();
        foreach (String word in words)
        {
            if((sentence.Length + word.Length) <= maxLength)
            {
                sentence.Append(word + " ");

            }
            else
            {
                Line.Add(sentence.ToString().Trim());
                sentence = new StringBuilder(word + " ");
            }
        }

        if (sentence.Length > 0)
            Line.Add(sentence.ToString().Trim());

        return Line;
    }

    private void btnSplitText_Click(object sender, EventArgs e)
    {
        List<String> Line = new List<string>();
        string message = "The quick brown fox jumps over the lazy dog.";
        Line = FormatMe(message);
    }

另一个 ...

public static string SplitLongWords(string text, int maxWordLength)
{
    var reg = new Regex(@"\S{" + (maxWordLength + 1) + ",}");
    bool replaced;
    do
    {
        replaced = false;
        text = reg.Replace(text, (m) =>
        {
            replaced = true;
            return m.Value.Insert(maxWordLength, " ");                    
        });
    } while (replaced);

    return text;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM