2013-06-22 18 views
0

我想節省一些時間,而不是手動測試解析文件中的每個標記,但似乎我不知道如何正確使用java.util.Scanner類的skip(String)方法。如何在使用java.util.Scanner對象的方法skip(String)時忽略換行符?

重新說明這個問題:我該如何讓兩個測試都通過?

import java.io.StringReader; 
import java.util.Scanner; 
import junit.framework.Assert; 
import org.junit.Test; 

public class ScannerTest { 

    static private final String text = "FUNCTION_BLOCK Unnamed_project\n\tVAR_INPUT\n\t\tUnnamed_variable1 : REAL;\n\tEND_VAR\nEND_FUNCTION_BLOCK"; 

    @Test 
    public void scannerSkipTest() { 

     Scanner sc = new Scanner(new StringReader(text)); 
     sc.skip("(?i)FUNCTION_BLOCK"); 
     String blockName = sc.next(); 
     assert sc.hasNext("(?i)VAR_INPUT");   // added test 
     sc.skip("(?i)VAR_INPUT");        // line of failure 
     String variableName = sc.next(); 
     sc.skip(":"); 
     String type = sc.next(); 
     sc.skip("(?i)END_VAR"); 
     sc.skip("(?i)END_FUNCTION_BLOCK"); 

     assert "Unnamed_project".equals(blockName); 
     assert "Unnamed_variable1".equals(variableName); 
     assert "REAL".equals(type); 
    } 

    @Test 
    public void scannerWithoutSkipTest() { 
     Scanner sc = new Scanner(new StringReader(text)); 
     String skipped = sc.next(); 
     assert "FUNCTION_BLOCK".equalsIgnoreCase(skipped); 
     String blockName = sc.next(); 
     skipped = sc.next(); 
     assert "VAR_INPUT".equalsIgnoreCase(skipped); 
     String variableName = sc.next(); 
     skipped = sc.next(); 
     assert ":".equalsIgnoreCase(skipped); 
     String type = sc.next(); 
     skipped = sc.next(); 
     assert "END_VAR".equalsIgnoreCase(skipped); 
     skipped = sc.next(); 
     assert "END_FUNCTION_BLOCK".equalsIgnoreCase(skipped); 

     assert "Unnamed_project".equals(blockName); 
     assert "Unnamed_variable1".equals(variableName); 
     assert "REAL".equals(type); 
    } 
} 

任何提示和提示讚賞。

+0

找到了正確的方法做,這是包圍用'next'機智取代所有'skip'方法調用hout存儲結果。 – Tuto

回答

1

Tuto,感謝您在試用後編輯我的答案,我會把你寫的內容重新寫在頂部的解釋。

基本上,當想要跳過帶有skip()的令牌時,首先需要跳過空白。相反,next()方法會自動執行此操作。

根據JavaDoc:

的next()和hasNext()方法及其基本類型companion方法(如nextInt()和hasNextInt())首先跳過與分隔符模式匹配的任何輸入,然後嘗試返回下一個令牌。

因此,通過使用sc.skip(WHITESPACE + "abc"),您可以跳過任何空格然後標記abc。結果是這樣的:

public class ScannerTest { 

    static private final String text = "FUNCTION_BLOCK Unnamed_project\n\tVAR_INPUT\n\t\tUnnamed_variable1 : REAL;\n\tEND_VAR\nEND_FUNCTION_BLOCK"; 
    public static final String WHITESPACE = "[ \\n\\t]+"; 

    @Test 
    public void scannerSkipTest() { 

     Scanner sc = new Scanner(new StringReader(text)); 
     sc.useDelimiter(WHITESPACE); 
     sc.skip("FUNCTION_BLOCK"); 
     String blockName = sc.next(); 
     sc.skip(WHITESPACE + "VAR_INPUT"); 
     String variableName = sc.next(); 
     sc.skip(WHITESPACE + ":"); 
     String typeWithSemiColon = sc.next(); 
     sc.skip(WHITESPACE + "END_VAR"); 
     sc.skip(WHITESPACE + "END_FUNCTION_BLOCK"); 

     assert "Unnamed_project".equals(blockName); 
     assert "Unnamed_variable1".equals(variableName); 
     assert "REAL;".equals(typeWithSemiColon); 
    } 
} 

注意,掃描儀仍然不會從;因爲分號是不是真的空白分裂REAL - 我離開,作爲一個exercice你要弄清楚:)

+0

感謝您的幫助。我將通過在第一個測試中增加一個斷言行來編輯問題示例。顯示,它應該通過默認的delimeters。 – Tuto

+0

Doh,我沒有馬上看到您爲所有跳躍模式添加了前綴。再次感謝您提供更好的解決方法。 – Tuto

0

僅供參考,我在原始問題上發佈了一個更清晰的解決方案,以及解決由vikingsteve公開的分號挑戰。

這裏是更正的測試方法。

注:

  • 分隔符\b使用方法next代替skip可選空間
  • 跳過關鍵字

@Test 
public void scannerSkipTest() { 

    Scanner sc = new Scanner(new StringReader(text)); 
    sc.useDelimiter("\\s*\\b\\s*|\\s+"); 

    sc.next("(?i)FUNCTION_BLOCK"); 
    String blockName = sc.next(); 
    sc.next("(?i)VAR_INPUT"); 
    String variableName = sc.next(); 
    sc.next(":"); 
    String type = sc.next(); 
    sc.next(";"); 
    sc.next("(?i)END_VAR"); 
    sc.next("(?i)END_FUNCTION_BLOCK"); 

    assert "Unnamed_project".equals(blockName); 
    assert "Unnamed_variable1".equals(variableName); 
    assert "REAL".equals(type); 

    sc.close(); 
}