2009-06-18 44 views
2

在java中,我想逐行讀取文件並將行打印到輸出。 我想用正則表達式來解決這個問題。java正則表達式行

while (...) 
{ 
    private static java.util.regex.Pattern line = java.util.regex.Pattern.compile(".*\\n"); 
    System.out.print(scanner.next(line)); 
} 

代碼中的正則表達式不正確,因爲我得到InputMismatchException。 我正在使用這個正則表達式2個小時。請幫忙。

隨着正則表達式powertoy我看到「。* \ n」是正確的。但我的程序運行不正確。

整個源是:

/** 
* Extracts the points in the standard input in off file format to the standard output in ascii points format. 
*/ 

import java.util.regex.Pattern; 
import java.util.Scanner; 

class off_to_ascii_points 
{ 
    private static Scanner scanner = new Scanner(System.in);  
    private static Pattern fat_word_pattern = Pattern.compile("\\s*\\S*\\s*"); 
    private static Pattern line = Pattern.compile(".*\\n", Pattern.MULTILINE); 

    public static void main(String[] args) 
    { 
     try 
     { 
      scanner.useLocale(java.util.Locale.US); 

        /* skip to the number of points */ 
      scanner.skip(fat_word_pattern); 

      int n_points = scanner.nextInt(); 

        /* skip the rest of the 2. line */ 
      scanner.skip(fat_word_pattern); scanner.skip(fat_word_pattern); 

      for (int i = 0; i < n_points; ++i) 
      { 
        System.out.print(scanner.next(line)); 
         /* 
         Here my mistake is. 
         next() reads only until the delimiter, 
         which is by default any white-space-sequence. 
         That is next() does not read till the end of the line 
         what i wanted. 

         Changing "next(line)" to "nextLine()" solves the problem. 
         Also, setting the delimiter to line_separator 
         right before the loop solves the problem too. 
         */ 
      } 

     } 
     catch(java.lang.Exception e) 
     { 
      System.err.println("exception"); 
      e.printStackTrace(); 
     } 
    } 
} 

的示例輸入的開始是:

OFF 
4999996 10000000 0 
-28.6663 -11.3788 -58.8252 
-28.5917 -11.329 -58.8287 
-28.5103 -11.4786 -58.8651 
-28.8888 -11.7784 -58.9071 
-29.6105 -11.2297 -58.6101 
-29.1189 -11.429 -58.7828 
-29.4967 -11.7289 -58.787 
-29.1581 -11.8285 -58.8766 
-30.0735 -11.6798 -58.5941 
-29.9395 -11.2302 -58.4986 
-29.7318 -11.5794 -58.6753 
-29.0862 -11.1293 -58.7048 
-30.2359 -11.6801 -58.5331 
-30.2021 -11.3805 -58.4527 
-30.3594 -11.3808 -58.3798 

我首先跳到其是含有點座標的行數數4999996。這些行是我試圖寫入輸出。

回答

4

我建議使用

private static Pattern line = Pattern.compile(".*"); 

scanner.useDelimiter("[\\r\\n]+"); // Insert right before the for-loop 

System.out.println(scanner.next(line)); //Replace print with println 

爲什麼按照預期的代碼不起作用:

這與您使用的掃描儀類,以及如何類的工作要做。

的Javadoc狀態:

掃描器斷開其輸入到使用定界符圖案,其通過 默認與空白匹配 。

這意味着當您調用其中一個Scanner's.next *方法時,掃描器會讀取指定的輸入,直到遇到下一個分隔符。

所以你要scanner.next(line)第一個電話開始讀取下面一行

-28.6663 -11.3788 -58.8252 

而在-28.6663後面的空格停止。然後它檢查標記(-28.6663)是否與您提供的模式(。* \ n)匹配,顯然不匹配(-28.6663)。這就是爲什麼。

+0

添加一節來解釋代碼失敗的原因 – jitter 2009-06-18 14:57:53

0

您必須將Pattern切換爲多行模式。

line = Pattern.compile("^.*$", Pattern.MULTILINE); 
System.out.println(scanner.next(line)); 
+0

MULTILINE也無法正常工作。 $字符對我來說還不夠,因爲我希望new_line字符被包含到匹配的字符串中。 – libeako 2009-06-18 12:56:21

0

默認情況下,掃描儀使用空格作爲分隔符。在第一次跳過之後讀取該行之前,必須將分隔符更改爲新行。您需要更改的代碼是在for循環之前插入以下行:

scanner.useDelimiter(Pattern.compile(System.getProperty(「line.separator」)));

並更新模式變線如下:

私有靜態圖案線= Pattern.compile( 「*」,圖案。多行);

+0

不要依賴「line.separator」屬性。任何給定的文件都可以使用任何樣式的行分隔符,甚至可以使用兩種樣式的混合。掃描儀的hasNextLine()和nextLine()方法將這些考慮在內。 – 2009-06-19 08:05:17

1

如果您只想將文件打印到標準輸出,爲什麼要使用正則表達式?如果你知道你總是想跳過前兩行,那麼有更簡單的方法來完成它。

import java.util.Scanner; 
import java.io.File; 

public class TestClass { 
    public static void main(String[] args) throws Exception { 
     Scanner in=new Scanner(new File("test.txt")); 
     in.useDelimiter("\n"); // Or whatever line delimiter is appropriate 
     in.next(); in.next(); // Skip first two lines 
     while(in.hasNext()) 
      System.out.println(in.next()); 
    } 
} 
+0

我必須閱讀行數。這是第2行中的第一個單詞。 – libeako 2009-06-18 13:46:31

0

感謝大家的幫助。

現在我明白了我的錯誤:

的API文檔指出,該掃描儀類的每個nextT()方法首先跳過與分隔符模式,然後嘗試讀取一件T值。然而,它忘記說,每個下一個...()方法只讀取,直到第一次出現分隔符!