web-dev-qa-db-ja.com

System.getProperty( "line.separator")。toString()を使用するにはどうすればよいですか?

メソッドに渡されるタブ区切り文字列(テーブルを表す)があります。コマンドラインに出力すると、行のあるテーブルのように表示されます。

http://i.stack.imgur.com/2fAyq.gif

コマンドウィンドウは正しくバッファリングされます。私の考えでは、各行の前または後には必ず改行文字があります。

私の問題は、着信文字列をテーブルの行を表す個々の文字列に分割することです。これまでのところ:

private static final String newLine = System.getProperty("line.separator").toString();
private static final String tab = "\t";
private static String[] rows;
...

rows = tabDelimitedTable.split(newLine);    //problem is here

System.out.println();
System.out.println("################### start debug ####################");

System.out.println((tabDelimitedTable.contains(newLine)) ? "True" : "False");

System.out.println("#################### end debug###################");
System.out.println();

出力:

################### start debug ####################
False
#################### end debug###################

明らかに、文字列の中に、OSに新しい行を開始するよう指示する何かがあります。しかし、明らかに改行文字は含まれていません。

Windowsで最新のJDKを実行するXP SP3。

何か案は?

21
ejsuncy

試して

rows = tabDelimitedTable.split("[" + newLine + "]");

これでregexの問題が解決するはずです。

また、それほど重要ではありませんが、

System.getProperty("line.separator")

Stringなので、toString()を呼び出す必要はありません。

28
Kerem Baydoğan

問題

[〜#〜] not [〜#〜]任意の入力テキストファイルが「正しい」プラットフォーム固有の 改行 セパレーター。これが問題の原因のようです。正規表現とはほとんど関係ありません。

たとえば、Windowsプラットフォームでは、System.getProperty("line.separator")は_"\r\n"_(CR + LF)です。ただし、このプラットフォームでJavaコードを実行する場合、行区切り記号が_"\n"_(LF)である入力ファイルを処理する必要がある場合があります。このファイルはもともとUnixプラットフォームで作成され、その後バイナリ(テキストの代わりに)モードでWindowsに転送されます。現在のテキストを使用しない入力としてテキストファイルを解析する必要がある、このような状況に陥る多くのシナリオがあります。プラットフォームの改行セパレータ。

(偶然にも、WindowsテキストファイルがバイナリモードでUnixに転送されると、多くのエディターは_^M_を表示し、何が起こっているのか理解していない一部の人々を混乱させました)。

出力としてテキストファイルを)生成する場合、おそらくプラットフォーム固有の改行セパレータを好むはずですが、consumingテキストファイルを入力として使用する場合、プラットフォーム固有の改行セパレータを正しく使用していると仮定するのはおそらく安全ではありません。


ソリューション

問題を解決する1つの方法は、たとえば _Java.util.Scanner_ 。プラットフォームには、次の行(存在する場合)を返すことができる nextLine() メソッドがあり、プラットフォームの改行セパレータと入力テキストファイル間の矛盾を正しく処理します。

また、2つのScannerを組み合わせて、1つはファイルを1行ずつスキャンし、もう1つは各行のトークンをスキャンできます。以下に、各行を _List<String>_ に分割する簡単な使用例を示します。したがって、ファイル全体は_List<List<String>>_になります。

これはおそらく、ファイル全体を1つの巨大なStringに読み込んでからsplitを行に読み込む(その後にsplitを部分に読み込む)よりも良い方法です。

_    String text
        = "row1\tblah\tblah\tblah\n"
        + "row2\t1\t2\t3\t4\r\n"
        + "row3\tA\tB\tC\r"
        + "row4";

    System.out.println(text);
    //  row1    blah    blah    blah
    //  row2    1   2   3   4
    //  row3    A   B   C
    //  row4

    List<List<String>> input = new ArrayList<List<String>>();

    Scanner sc = new Scanner(text);
    while (sc.hasNextLine()) {
        Scanner lineSc = new Scanner(sc.nextLine()).useDelimiter("\t");
        List<String> line = new ArrayList<String>();
        while (lineSc.hasNext()) {
            line.add(lineSc.next());
        }
        input.add(line);
    }
    System.out.println(input);
    // [[row1, blah, blah, blah], [row2, 1, 2, 3, 4], [row3, A, B, C], [row4]]
_

こちらもご覧ください

  • Effective Java 2nd Edition、Item 25:リストを配列より優先する

関連する質問

30

Windowsでは、line.separatorはCR/LFの組み合わせです(参照 ここ )。

Java String.split()メソッドは 正規表現 を取るため、ここで混乱が生じると思います。

2
Brian Agnew

このすべての複雑さの代わりにBufferedReader.readLine()を試してください。考えられるすべての行末記号を認識します。

2
user207421

これを試して:

rows = tabDelimitedTable.split("[\\r\\n]+");

これは、入力に含まれる行区切り文字に関係なく機能し、空白行は無視されます。

1
James Van Huis

あなたの問題は、String.split()が引数を正規表現として扱い、正規表現が改行を特別に扱うことだと思います。 split()(別のオーバーロードがあります)に渡す正規表現オブジェクトを明示的に作成し、Pattern.compile()のflagsパラメーターにMULTILINEを渡すことで改行を許可するように正規表現を構成する必要があります。 ドキュメント

1
rmeador

他のレスポンダーは、split()が引数として正規表現を使用するので正しいので、最初に修正する必要があります。もう1つの問題は、改行文字がシステムのデフォルトと同じであると仮定していることです。データの送信元およびプログラムの実行場所によっては、この仮定が正しくない場合があります。

1
Mike Baranczak