.NETで文字列を改行に分割する必要があります。文字列を分割する唯一の方法は、Splitメソッドを使用することです。しかし、それは私が(簡単に)改行で分割することを許可しないので、それを行うための最良の方法は何ですか?
.NETで文字列を改行に分割する必要があります。文字列を分割する唯一の方法は、Splitメソッドを使用することです。しかし、それは私が(簡単に)改行で分割することを許可しないので、それを行うための最良の方法は何ですか?
回答:
文字列を分割するには、文字列の配列を受け取るオーバーロードを使用する必要があります。
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
残して分割し\r
、その後、行と行の\r\n
間に行を出力します。
\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を使用しないようにしてください。関数を使用するすべての場所で、より多くのメモリを使用するためです。元の文字列と分割コピーの両方がメモリ内にあります。これは、スケーリングを開始するときに問題の1つになる可能性があると私に信じてください。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
、あなたはそれを拡張メソッドにしている仮引数を入れているのを見ます。
文字列変数の場合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では、新しい行ごとに1つの空の文字列要素が作成されるため、セパレーターで分割します。正規表現もオプションです:
private string[] SplitStringByLineFeed(string inpString)
{
string[] locResult = Regex.Split(inpString, "[\r\n]+");
return locResult;
}
"\r?\n"
。
この質問の他の解決策は再利用可能なコード分類に分類されず、便利ではないので、2ビットを追加すると思いました。
次のコードブロックは、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
が失敗するのは、改行に別の方法を使用する他のプログラムによって保存されたファイルを使用している場合です。読み込まれるファイルが常に現在のOSの改行を使用していることがわかっている場合は、問題なく機能します。
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
最初にプラットフォームローカルの改行で分割を試み、次に可能な各改行にフォールバックします。
これまでのところ、これは1つのクラス内でのみ必要でした。それが変更された場合は、おそらくこれ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]);
}
string[] lines = text.Split(
Environment.NewLine.ToCharArray(),
StringSplitOptions.RemoveEmptyStrings);
RemoveEmptyStringsのオプションは、\ rの次に起因\ nまでの空のエントリを持っていないことを確認します
(コメントを反映するように編集します。)また、テキスト内の純粋な空行も破棄されます。これは通常私が欲しいものですが、あなたの要件ではないかもしれません。
Environment.Newlineについては知りませんでしたが、これは非常に良い解決策だと思います。
私の試みはされていたでしょう:
string str = "Test Me\r\nTest Me\nTest Me";
var splitted = str.Split('\n').Select(s => s.Trim()).ToArray();
追加の.Trimは、まだ存在する可能性のある\ rまたは\ nをすべて削除します(たとえば、ウィンドウ上にあるが、文字列を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/en-us/library/...をし、それが言うことは、ゼロバイトのファイル&リターン「そのファイルのフルパス」を作成します。私は以前にこれを試したと誓うことができました、そしてそれはそれがファイルを見つけなかったので例外を与えましたが、代わりにフォルダの場所が返されました。私はの使用に関する引数を知っ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と同じです。