Answers:
要分割字符串,您需要使用采用字符串数组的重载:
string[] lines = theText.Split(
new[] { Environment.NewLine },
StringSplitOptions.None
);
编辑:
如果要处理文本中不同类型的换行符,则可以使用该功能来匹配多个字符串。这将在两种类型的换行符上正确分割,并保留文本中的空行和空格:
string[] lines = theText.Split(
new[] { "\r\n", "\r", "\n" },
StringSplitOptions.None
);
Environment.NewLine
属性包含系统的默认换行符。以Windows系统为例"\r\n"
。
\n
留下a的情况\r
下拆分,然后在两行\r\n
之间输出a 。
\r
和换\n
码序列(以及其他)对C#编译器有特殊的含义。VB没有这些转义序列,因此使用了这些常量。
怎么样使用StringReader
?
using (System.IO.StringReader reader = new System.IO.StringReader(input)) {
string line = reader.ReadLine();
}
while
答案。
您应该能够轻松拆分字符串,如下所示:
aString.Split(Environment.NewLine.ToCharArray());
尽量避免使用string.Split作为一般解决方案,因为在使用该函数的任何地方都会使用更多的内存-原始字符串和拆分副本都在内存中。相信我,当您开始扩展时,这可能是个棘手的问题-运行一个处理100MB文档的32位批处理应用程序,您将遇到8个并发线程。不是说我去过那里...
相反,使用这样的迭代器;
public static IEnumerable<string> SplitToLines(this string input)
{
if (input == null)
{
yield break;
}
using (System.IO.StringReader reader = new System.IO.StringReader(input))
{
string line;
while( (line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
这将使您可以在数据周围进行更有效的内存循环。
foreach(var line in document.SplitToLines())
{
// one line at a time...
}
当然,如果您希望将其全部存储在内存中,则可以执行此操作。
var allTheLines = document.SplitToLines.ToArray();
blah.SplitToLines..
例如document.SplitToLines...
?
this
输入了形式参数,使其成为扩展方法。
根据Guffa的答案,在扩展类中,使用:
public static string[] Lines(this string source) {
return source.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
}
对于字符串变量s
:
s.Split(new string[]{Environment.NewLine},StringSplitOptions.None)
这将使用您环境的行尾定义。在Windows上,行尾为CR-LF(回车,换行)或C#的转义字符\r\n
。
这是一个可靠的解决方案,因为如果您将的行与合并String.Join
,则等于原始字符串:
var lines = s.Split(new string[]{Environment.NewLine},StringSplitOptions.None);
var reconstituted = String.Join(Environment.NewLine,lines);
Debug.Assert(s==reconstituted);
不该做什么:
StringSplitOptions.RemoveEmptyEntries
,因为这会破坏标记(例如Markdown),其中空行具有语法目的。new char[]{Environment.NewLine}
,因为在Windows上,这将为每个新行创建一个空字符串元素。我只是以为我要加上两位,因为这个问题的其他解决方案不属于可重用的代码分类,而且也不方便。
以下代码块扩展了string
对象,以便在使用字符串时可以将其作为自然方法使用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Collections.ObjectModel;
namespace System
{
public static class StringExtensions
{
public static string[] Split(this string s, string delimiter, StringSplitOptions options = StringSplitOptions.None)
{
return s.Split(new string[] { delimiter }, options);
}
}
}
现在,您可以.Split()
从任何字符串使用函数,如下所示:
string[] result;
// Pass a string, and the delimiter
result = string.Split("My simple string", " ");
// Split an existing string by delimiter only
string foo = "my - string - i - want - split";
result = foo.Split("-");
// You can even pass the split options parameter. When omitted it is
// set to StringSplitOptions.None
result = foo.Split("-", StringSplitOptions.RemoveEmptyEntries);
要分割换行符,只需传递 "\n"
或"\r\n"
作为定界符参数即可。
注释: 如果Microsoft实现了此重载,那就太好了。
Environment.Newline
优先于\n
或进行硬编码\r\n
。
Environment.Newline
用于跨平台兼容性,不适用于使用与当前操作系统不同的线路终端的文件。有关更多信息,请参见此处,因此它实际上取决于开发人员正在使用什么工具。使用Environment.Newline
确保确保OS之间的行返回类型不一致,其中“硬编码”使开发人员可以完全控制。
.Newline
这不是魔术,在引擎盖下,它只是上面提供的字符串(基于它是在unix还是在Windows上运行)的切换。最安全的选择是,首先用字符串替换所有“ \ r \ n”,然后在“ \ n”上分割。使用.Newline
失败的地方是当您处理由其他程序使用换行符的其他方法保存的文件时。如果您每次都始终使用当前操作系统的换行符来读取文件,则此方法很好用。
foo = foo.Replace("\r\n", "\n"); string[] result = foo.Split('\n');
。我是否正确理解这适用于所有平台?
我目前在VB.NET中使用此功能(基于其他答案):
Private Shared Function SplitLines(text As String) As String()
Return text.Split({Environment.NewLine, vbCrLf, vbLf}, StringSplitOptions.None)
End Function
它尝试首先在平台本地的换行符上分割,然后回退到每个可能的换行符。
到目前为止,我只需要在一堂课中使用它。如果那改变了,我可能会做这个Public
并将其移至实用程序类,甚至可能使其成为扩展方法。
很好地说明了如何加入备份行:
Private Shared Function JoinLines(lines As IEnumerable(Of String)) As String
Return String.Join(Environment.NewLine, lines)
End Function
好吧,实际上拆分应该可以:
//Constructing string...
StringBuilder sb = new StringBuilder();
sb.AppendLine("first line");
sb.AppendLine("second line");
sb.AppendLine("third line");
string s = sb.ToString();
Console.WriteLine(s);
//Splitting multiline string into separate lines
string[] splitted = s.Split(new string[] {System.Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
// Output (separate lines)
for( int i = 0; i < splitted.Count(); i++ )
{
Console.WriteLine("{0}: {1}", i, splitted[i]);
}
我不知道Environment.Newline,但是我想这是一个很好的解决方案。
我的尝试是:
string str = "Test Me\r\nTest Me\nTest Me";
var splitted = str.Split('\n').Select(s => s.Trim()).ToArray();
附加的.Trim删除可能仍然存在的任何\ r或\ n(例如,在Windows上但使用os x换行符分割字符串时)。可能不是最快的方法。
编辑:
正如注释正确指出的那样,这还会删除行首或换行之前的所有空格。如果需要保留该空格,请使用其他选项之一。
愚蠢的答案:写入临时文件,以便可以使用古老的文件
File.ReadLines
var s = "Hello\r\nWorld";
var path = Path.GetTempFileName();
using (var writer = new StreamWriter(path))
{
writer.Write(s);
}
var lines = File.ReadLines(path);
var
,因为它没有定义变量的类型,因此您可能不了解如何使用该对象或该对象表示什么。另外,这显示了编写各行,甚至没有指定文件名,因此我怀疑它是否可以工作。然后,在读取时,再次未指定文件的路径。假设path
是C:\Temp\test.txt
,那么您应该拥有string[] lines = File.ReadLines(path);
。
Path.GetTempFileName
msdn.microsoft.com/zh-cn/library/…,它说它创建了一个零字节的文件并返回“该文件的完整路径”。我可以发誓之前尝试过此方法,但它却出现了异常,因为它没有找到文件,而是返回了文件夹位置。我知道使用using的参数var
,但是我不建议您使用它,因为它没有显示变量对象是什么。它混淆了它。
实际上很简单。
VB.NET:
Private Function SplitOnNewLine(input as String) As String
Return input.Split(Environment.NewLine)
End Function
C#:
string splitOnNewLine(string input)
{
return input.split(environment.newline);
}
Environment.NewLine
就像在VB中一样。