如何在保留行结尾的同时拆分字符串?

时间:2009-01-29 17:58:34

标签: c# .net string split

我有一个文本块,我希望它的行没有在最后丢失\ r和\ n。现在,我有以下(次优代码):

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

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

接受的答案

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

6 个答案:

答案 0 :(得分:6)

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

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

(?&lt; = \ r \ n)在\ r \ n之后使用'正向lookbehind'匹配而不消耗它。

(?!$)使用负前瞻来阻止输入结束时的匹配,从而避免最后一行只是一个空字符串。

答案 1 :(得分: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();

答案 2 :(得分:0)

使用这个正则表达式的东西: [^ \ n \ R] * \ r \ n

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

答案 3 :(得分:0)

德米特里,你的解决方案实际上非常紧凑和简单。唯一更有效的方法是 保持 生成的数组中的字符串分割字符,但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的一次一个,然后自己创建阵列。但是,这显然是更多的代码,并且可能没有必要。

您的解决方案和此解决方案的副作用之一是 不会 在最后一行终止“\ r \ n”不是TextBox中已有的那个。这是你期望的吗?空白行怎么样......你希望它们出现在“行”中吗?

答案 4 :(得分: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;
    }

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

答案 5 :(得分: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);
        }

输出:

一,

二,

三,