Java регулярное выражение - PullRequest
2 голосов
/ 18 июня 2009

В Java я хотел бы прочитать файл строка за строкой и распечатать строку для вывода. Я хочу решить это с помощью регулярных выражений.

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

Регулярное выражение в коде не правильно, так как я получаю InputMismatchException. Я работаю над этим регулярным выражением в течение 2 часов. Пожалуйста, помогите с этим.

С помощью regex 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, который является числом строк, содержащих координаты точки. Эти строки, которые я пытаюсь записать в вывод.

Ответы [ 5 ]

4 голосов
/ 18 июня 2009

Я предлагаю использовать

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

Почему ваш код не работает должным образом:

Это связано с используемым вами классом Scanner и с тем, как работает этот класс.

Javadoc утверждает:

Сканер разбивает свой вход на токены используя шаблон разделителя, который путем по умолчанию соответствует пробелу.

Это означает, что при вызове одного из методов Scanner's.next * сканер считывает указанный ввод, пока не встретится следующий разделитель.

Итак, ваш первый вызов scanner.next(line) начинает читать следующую строку

-28.6663 -11.3788 -58.8252 

И останавливается на месте после -28.6663. Затем он проверяет, соответствует ли токен (-28.6663) указанному вами шаблону (. * \ N), который явно не соответствует (-28.6663). Вот почему.

1 голос
/ 18 июня 2009

Если вы хотите распечатать файл только в стандартном формате, почему вы хотите использовать регулярные выражения? Если вы знаете, что всегда хотите пропустить первые две строки, есть более простые способы сделать это.

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 голосов
/ 19 июня 2009

Спасибо всем за помощь.

Теперь я понимаю свою ошибку:

В документации API говорится, что каждый метод nextT () класса Scanner сначала пропускает шаблон разделителя, а затем пытается прочитать значение T. Однако он забывает сказать, что каждый следующий метод ... () читает только до первого появления разделителя!

0 голосов
/ 18 июня 2009

По умолчанию сканер использует пробел в качестве разделителя. Вы должны изменить разделитель на новую строку, прежде чем читать строку после первого пропуска. Код, который вам нужно изменить, это вставить следующую строку перед циклом for:

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

и обновите строку переменной Pattern следующим образом:

приватная статическая строка Pattern = Pattern.compile (". *", Pattern.MULTILINE);

0 голосов
/ 18 июня 2009

Вы должны переключить Pattern в многострочный режим.

line = Pattern.compile("^.*$", Pattern.MULTILINE);
System.out.println(scanner.next(line));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...