2017-01-30 8 views
0

Scannerの次のトークンに特定の文字列が含まれているかどうかを確認しようとしています。しかし、トークンに\ nまたは\ rがある場合、hasNext(String)メソッドは何があってもfalseを返します。 (私はEclipseを使用しています)スキャナhasNext()メソッドとエスケープ文字

デフォルトの区切り文字(スペース)では問題は発生しません。しかし、useDelimiter()を使用すると、区切り文字を ""に設定する場合でも、hasNext(String)は常にfalseを返します。

ScannerhasNext(String)メソッドは、トークンのどこかにエスケープ文字があり、区切り文字もリセットされた場合、常にfalseを返しますか?

import java.util.*; 

public class ScannerDemo { 

    public static void main(String[] args) { 

     Scanner scanner = new Scanner("abcdefg\n\rX"); 
     scanner.useDelimiter("X"); 

     // Returns false!! Why? 
     System.out.println("" + scanner.hasNext(".*c.*")); 
     System.out.println(scanner.next()); 
     System.out.println("-------------------------------"); 

     scanner.close(); 

     scanner = new Scanner("abcde\n\rXfg"); 
     scanner.useDelimiter("X"); 

     // Returns false!! Why? 
     System.out.println("" + scanner.hasNext(".*c.*")); 
     System.out.println(scanner.next()); 
     System.out.println("-------------------------------"); 

     scanner.close(); 

     scanner = new Scanner("\n\rabcdeXfg"); 
     scanner.useDelimiter("X"); 

     // Returns false!! Why? 
     System.out.println("" + scanner.hasNext(".*c.*")); 
     System.out.println(scanner.next()); 
     System.out.println("-------------------------------"); 

     scanner.close(); 

     scanner = new Scanner("abcdeXfg\n\r"); 
     scanner.useDelimiter("X"); 

     // Returns true, as expected 
     System.out.println("" + scanner.hasNext(".*c.*")); 
     System.out.println(scanner.next()); 
     System.out.println("-------------------------------"); 

     scanner.close(); 

     scanner = new Scanner("abcdeXfg"); 
     scanner.useDelimiter("X"); 

     // Returns true, as expected 
     System.out.println("" + scanner.hasNext(".*c.*")); 
     System.out.println(scanner.next()); 
     System.out.println("-------------------------------"); 

     scanner.close(); 

    } 
} 

答えて

1

正規表現のワイルドカード文字は、デフォルトで\r\nと一致しません。

あなたはフラグDOTALLを指定する必要がありますが、あなたが直接Patternクラスを使用していないことから、あなたの正規表現に(?s)を追加することによってそれを行う:

scanner.hasNext("(?s).*c.*") 

DOTALL javadocはそれを言うように:

dotallモードでは、式.は行終端文字を含む任意の文字に一致します。デフォルトでは、この式は行ターミネータと一致しません。

これは、Patternのjavadocの.の説明で覆われている。

.      任意の文字(またはline terminatorsと一致してもしなくてもよい)

リンクは:

正規表現.は、DOTALLフラグが指定されていない限り、行終了記号を除くすべての文字と一致します。

+0

'(?s)'を正規表現に追加することは、確かにそのトリックです。私はまだ\ r \ nが問題を引き起こすべき理由を理解していない - それらは私がマッチさせようとしている文字ではありません。そして、なぜuseDelimiter()が問題に影響を与えるのかわかりません。 –

+0

@MaeWarren 'useDelimiter(" X ")'を指定すると、最初のトークンは 'abcdefg \ n \ r'なので、' hasNext( "。* c。*") 'を呼び出すと、最初の'。* ''は 'ab'にマッチし、' c'は 'c'にマッチしますが、'。* 'は行終端文字にマッチすることができない限り、defg \ n \ r' *と一致しません。 – Andreas

+0

私は参照してください。私はこれが完全に質問に答えると信じています。どうも。 –

0

hereにチェックしてください。そこでの答えの1つは、

"その中に.next()を持つ時計がある場合、IDEは実際にはそれぞれのカーソル位置を進めています。" --Amalgovinus

これは問題が発生している可能性があります。

+0

これはそうではありません。この問題はエスケープ文字がある場合にのみ発生します。そして、最初の.next()が実行される前に問題が発生します。 –

+0

Hm。私は今すぐ便利なIDEを持っていません(私は私の電話にいます)、そして私はその問題に遭遇したことをいつも覚えていません。 –

関連する問題