3

我有一段文本,我想在丢失结尾的 \r 和 \n 的情况下获得它的行。现在,我有以下(次优代码):

string[] lines = tbIn.Text.Split('\n')
                     .Select(t => t.Replace("\r", "\r\n")).ToArray();

所以我想知道 - 有没有更好的方法呢?

接受的答案

string[] lines =  Regex.Split(tbIn.Text, @"(?<=\r\n)(?!$)");
4

6 回答 6

6

以下似乎可以完成这项工作:

string[] lines =  Regex.Split(tbIn.Text, @"(?<=\r\n)(?!$)");

(?<=\r\n) 在 \r\n 之后使用“正向后视”来匹配而不消耗它。

(?!$) 使用负前瞻来防止在输入末尾匹配,从而避免最后一行只是一个空字符串。

于 2009-01-29T19:05:13.047 回答
0

如果您只是要替换换行符 ( \n),请执行以下操作:

string[] lines = tbIn.Text.Split('\n')
                     .Select(t => t + "\r\n").ToArray();

编辑:Regex.Replace 允许您拆分字符串。

string[] lines = Regex.Split(tbIn.Text, "\r\n")
             .Select(t => t + "\r\n").ToArray();
于 2009-01-29T18:08:00.743 回答
0

类似于使用此正则表达式的内容: [^\n\r]*\r\n

然后使用 Regex.Matches()。问题是您需要 Group(1) 从每个匹配项中创建您的字符串列表。在 Python 中,您只需使用 map() 函数。不确定在 .NET 中执行此操作的最佳方法,您可以从那里获取 ;-)

于 2009-01-29T18:11:01.050 回答
0

Dmitri,您的解决方案实际上非常简洁明了。唯一更有效的方法是将字符串拆分字符保留在生成的数组中,但 API 根本不允许这样做。因此,每个解决方案都需要遍历数组并执行某种修改(这在 C# 中意味着每次都分配新字符串)。我认为你能希望的最好的就是不要重新创建数组:

string[] lines = tbIn.Text.Split('\n');
for (int i = 0; i < lines.Length; ++i)
{
    lines[i] = lines[i].Replace("\r", "\r\n");
}

...但正如您所见,这看起来更麻烦!如果性能很重要,这可能会好一些。如果真的很重要,您应该考虑使用 IndexOf() 手动解析字符串,一次找到 '\r 的一个,然后自己创建数组。不过,这要多得多的代码,而且可能没有必要。

您的解决方案和这个解决方案的副作用之一是,如果 TextBox 中还没有最后一行,您将不会在最后一行获得终止的“\r\n”。这是你所期望的吗?空白行呢……您希望它们出现在“行”中吗?

于 2009-01-29T18:25:35.280 回答
0

您可以使用正则表达式来实现这一点。这是一个扩展方法:

    public static string[] SplitAndKeepDelimiter(this string input, string delimiter)
    {
        MatchCollection matches = Regex.Matches(input, @"[^" + delimiter + "]+(" + delimiter + "|$)", RegexOptions.Multiline);
        string[] result = new string[matches.Count];
        for (int i = 0; i < matches.Count ; i++)
        {
            result[i] = matches[i].Value;
        }
        return result;
    }

我不确定这是否是一个更好的解决方案。你的非常紧凑和简单。

于 2009-01-29T18:37:19.470 回答
0

与往常一样,扩展方法好东西:)

public static class StringExtensions
{
    public static IEnumerable<string> SplitAndKeep(this string s, string seperator)
    {
        string[] obj = s.Split(new string[] { seperator }, StringSplitOptions.None);

        for (int i = 0; i < obj.Length; i++)
        {
            string result = i == obj.Length - 1 ? obj[i] : obj[i] + seperator;
            yield return result;
        }
    }
}

用法:

        string text = "One,Two,Three,Four";
        foreach (var s in text.SplitAndKeep(","))
        {
            Console.WriteLine(s);
        }

输出:

一,

二,

三,

于 2009-01-29T18:38:48.217 回答