我有一个文本块,我希望它的行没有在最后丢失\ r和\ n。现在,我有以下(次优代码):
string[] lines = tbIn.Text.Split('\n')
.Select(t => t.Replace("\r", "\r\n")).ToArray();
所以我想知道 - 有更好的方法吗?
接受的答案
string[] lines = Regex.Split(tbIn.Text, @"(?<=\r\n)(?!$)");
答案 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();
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)
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);
}
输出:
一,
二,
三,
四