0

Scanner の内部がどのように機能するかをより明確に理解することを望んでいます... Scanner なしで必要なものを実装しましたが、これが思ったように機能しなかった理由を理解しようとしています。

コンテキスト: テキスト行の読み取り (ライン モード) から、同じ入力ストリームから設定されたバイト数の読み取り (バイト モード) に定期的に切り替える必要があるテキスト パーサーを作成しています。入力ストリームに BYTE\n が表示されると、バイト モードに入ります。読み取るバイト数を指定する整数が続くことが期待されます。有効な整数/バイト シーケンスの後に ENDBYTE\n が表示されると、バイト モードは終了します。

Scanner を使用して、このパーサーを区切り文字「\n」で実装し、「ライン モード」で読み取ろうとしました。デリミタをストリームの途中で「.{1}」の正規表現パターンに切り替えると、一度に 1 バイトが与えられ始め、「生モード」でデータを処理できるようになると思いました (これはメソッドが実際には InputStream の次のバイトを提供するだけではないことに気付く前に、 Scanner.nextByte() をいじるのに多くの時間を無駄にしました)。

このシーケンスを Scanner の InputStream に入れてみました。

BYTE\n32\nNegative, I am a meat popsicle.\nENDBYTE\n

「32\n」を解析するとすぐに、区切り文字を「.{1}」に変更してみます。次に next() を要求すると、"\n" が返され、スキャナは不思議なことにトークンが他にもあると報告しますが、それらは空であることが判明しました。区切り文字を「\n」のままにすると、「Negative、私は肉のアイスキャンディーです」と正しく表示されます。次のトークンとして。

したがって、次のいずれかを想定しています。

  1. ".{1}" は、私が意図したように 1 つの文字に一致するだけではありません...なぜそうなるのかわかりませんか?
  2. Scanner は、常にできる限り多くのデータを読み取り、先制的にデータをトークンに解析することで、InputStream を変更します。私はこれが真実であると信じる傾向があります.InputStream で available() 呼び出しの結果を出力したとき、区切り文字を "\n "。これは、処理中に区切り文字を変更すると、Scanner が非常に混乱し、結果として誤った動作をしているように見えることを意味します。

正規表現/スキャナーの専門知識をお持ちでしたら、よろしくお願いします。

PS私はInputStreamから個々のバイトを自分で読み込んで、ラインモードで手動で「\ n」を探しました...きれいではありませんが、私が望むように動作します。

4

1 に答える 1

1

正規表現".{1}"(ちなみに と同じ".") は、改行文字と一致しません。

改行を含む任意の文字に一致させるには、正規表現で「ドットが改行に一致」スイッチをオンにします。

(?s).


編集済み

区切り記号を使用しないことをお勧めします。次のように入力を消費するだけです:

while (scanner.hasNextLine()) {
    String line = scanner.nextLine();
    // do something with line
}
于 2012-07-06T18:42:12.300 に答える