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

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()を使用して文字列を手動で解析し、一度に1つずつ'\ rを見つけてから、自分で配列を作成することを検討する必要があります。ただし、これはかなり多くのコードであり、おそらく必要ではありません。

ソリューションとこのソリューションの両方の副作用の1つは、TextBoxまだ存在しない場合、最後の行に終了「\ r\n」が表示されないことです。これはあなたが期待することですか?空白行はどうですか...「行」に表示されると思いますか?

于 2009-01-29T18:25:35.280 に答える
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

これは正規表現で実現できます。拡張メソッドは次のとおりです。

    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);
        }

出力:

1、

二、

三、

于 2009-01-29T18:38:48.217 に答える