Сканирование текста с java.util.Scanner

J2SE 5.0 добавляет классов и методов, которые можно делать каждый день задачи легче выполнять. В этом совете вы увидите, как недавно добавили java.util.Scanner класс делает его легче читать и анализировать строки и примитивных типов с использованием регулярных выражений.

Перед J2SE 5.0 релиз, вы, вероятно, пишет код, такой как следующий класс TextReader читать текст из файла:


   import java.io.BufferedReader;

   import java.io.FileReader;

   import java.io.IOException;

   import java.io.File;



   public class TextReader {

     private static void readFile(String fileName) {

       try {

         File file = new File(fileName);

         FileReader reader = new FileReader(file);

         BufferedReader in = new BufferedReader(reader);

         String string;

         while ((string = in.readLine()) != null) {

           System.out.println(string);

         }

         in.close();

       catch (IOException e) {

         e.printStackTrace();

       }

     }



     public static void main(String[] args) {

       if (args.length != 1) {

         System.err.println("usage: java TextReader "

           "file location");

         System.exit(0);

       }

       readFile(args[0]);

     }

   }

Основной подход в классах, как это создать файл, объект, соответствующий фактический файл на жестком диске. Класс затем создает FileReader связанный с файлом, а затем BufferedReader от FileReader. Затем он использует BufferedFile читателя прочитать файл по одной строке за раз.

Для просмотра класс TextReader в действии, вы должны создать документ для данного класса чтения и синтаксического анализа. Чтобы создать документ, сохранить следующие две строки текста в файле с именем TextSample.txt в том же каталоге, TextReader:

Here is a small text file that you will
use to test java.util.scanner.

Обобщение TextReader ". Затем запустите ее, введя следующее:

java TextReader TextSample.txt

Вы должны увидеть оригинальный файл повторил обратно к вам в стандартный вывод.

Вы можете упростить код в TextReader помощью java.util.Scanner класс, который разбирает примитивных типов и строк:


   import java.io.File;

   import java.io.FileNotFoundException;

   import java.util.Scanner;



   public class TextScanner {



     private static void readFile(String fileName) {

       try {

         File file = new File(fileName);

         Scanner scanner = new Scanner(file);

         while (scanner.hasNext()) {

           System.out.println(scanner.next());

         }

         scanner.close();

       catch (FileNotFoundException e) {

         e.printStackTrace();

       }

     }



     public static void main(String[] args) {

       if (args.length != 1) {

         System.err.println("usage: java TextScanner1"

           "file location");

         System.exit(0);

       }

       readFile(args[0]);

     }

   }

Обобщение TextScanner. Затем запустите его следующим образом:

java TextScanner TextSample.txt

Вы должны получить следующие результаты:

Here
is
a
small
text
file
that
you
will
use
to
test
java.util.scanner.

TextScanner создает объект сканер из файла. Сканер перерывы содержимое файла в лексемы помощью разделяющем шаблоне, по умолчанию разделителем шаблон пробелом. TextScanner затем вызывает hasNext () в сканере. Этот метод возвращает значение "истина, если другой знак существует во входных сканера, как это имеет место, пока не достигнет конца файла. Следующий () возвращает строку, которая представляет собой следующий жетон. Так до достижения конца файла, TextScanner печатает строку, вернулись к следующему () на отдельной строке.

Вы можете изменить разделители, используемые для Разбивает вход, через useDelimiter метода сканера. Вы можете передать в строку или java.util.regex.Pattern методу. См. страницу Javadocs за образец для информации о том, что модели могут быть применены. Например, вы можете прочитать ввод одной строке за раз, используя символ новой строки (\\ п) в качестве разделителя. Вот пересмотренный ReadFile () метод TextScanner который использует символы новой строки в качестве разделителя:


   private static void readFile(String fileName) {

     try {

       Scanner scanner = new Scanner(new File(fileName));

       scanner.useDelimiter

         (System.getProperty("line.separator"))

       while (scanner.hasNext()) {

         System.out.println(scanner.next());

       scanner.close();

     catch (FileNotFoundException e) {

       e.printStackTrace();

     }

   

Обратите внимание, что существуют и другие возможности для обнаружения конца строки. Можно, например, тест на линиях, которые заканчиваются символом новой строки или заканчиваться символом возврата каретки и символа новой строки. Вы можете сделать это с использованием регулярных выражений "\\ R \\ N | \\ N". Javadocs для java.util.regex.Pattern показаны другие возможные терминаторы строки, так что более полная проверка будет использовать выражение "\\ R \\ п | [\\ R \\ N \\ u2028 \\ u2029 \\ u0085]". Вы также можете использовать hasNextLine () и nextLine () методы из класса сканера. В любом случае, с пересмотренным TextScanner, результат должен соответствовать содержанию и макет TextSample.txt. Другими словами, вы должны увидеть следующее:

Here is a small text file that you will
use to test java.util.scanner.

Простой смене шаблона в разделитель используются сканер дает вам большую силу и гибкость. Например, если задать следующий разделитель:

scanner.useDelimiter("\\z");

В ней написано весь файл сразу. Это похоже на хитрость предложила Пэт Нимайер java.net в своем блоге. Вы можете читать все содержимое веб-страницы без создания нескольких промежуточных объектов. Код следующий класс, WebPageScanner, говорится в текущем содержании java.net Домашняя страница:


   import java.net.URL;

   import java.net.URLConnection;

   import java.io.IOException;

   import java.util.Scanner;



   public class WebPageScanner {

     public static void main(String[] args) {

       try {

         URLConnection connection =

           new URL("http://java.net").openConnection();

         String text = new Scanner(

           connection.getInputStream()).

           useDelimiter("\\Z").next();

       catch (IOException e) {

         e.printStackTrace();

       }

     }

   }

Вы можете обрабатывать более строк с классом сканера. Вы также можете использовать сканер для анализа данных, который состоит из примитивов. Чтобы проиллюстрировать это, сохранить следующие три строки в файле с именем Employee.data (в том же каталоге, TextSample):

Joe, 38, true
Kay, 27, true
Lou, 33, false

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


   import java.util.Scanner;

   import java.io.File;

   import java.io.FileNotFoundException;



   public class DataScanner {



     private static void readFile(String fileName) {

       try {

         Scanner scanner =

           new Scanner(new File(fileName));

         scanner.useDelimiter

           (System.getProperty("line.separator"))

         while (scanner.hasNext()) {

           parseLine(scanner.next());

         }

         scanner.close();

       catch (FileNotFoundException e) {

         e.printStackTrace();

       }

     }



     private static void parseLine(String line) {

       Scanner lineScanner = new Scanner(line);

      lineScanner.useDelimiter("\\s*,\\s*");

       String name = lineScanner.next();

       int age = lineScanner.nextInt();

       boolean isCertified = lineScanner.nextBoolean();

       System.out.println("It is " + isCertified +

         " that " + name + ", age "

         + age + ", is certified.");

     }



     public static void main(String[] args) {

       if (args.length != 1) {

         System.err.println("usage: java TextScanner2"

           "file location");

         System.exit(0);

       }

       readFile(args[0]);

     }

   }

Космический объект в DataScanner Сканер считывает файл по одной строке за раз. ReadFile () метод проходит каждую строку второго сканера. Второй сканера анализирует разделенные запятыми данные и удаляет пробелы с обеих сторон запятыми. Существуют варианты hasNext () и Next () методы, которые позволят вам проверить является ли следующий маркер определенного типа и пытаться лечить следующий знак в качестве примера такого рода. Например, nextBoolean () пытается относиться к следующей лексемы как логическое и пытается сопоставить его либо строка "Правда" или строку "ложным". Если матч не может быть сделано, генерируется java.util.InputMismatchException. ParseLine () Метод DataScanner показано, как каждая строка анализируется в строку, INT, и логическое значение.

Обобщение DataScanner. Затем запустите его следующим образом:

java DataScanner Employee.data

Вы должны получить следующие результаты:

It is true that Joe, age 38, is certified.
It is true that Kay, age 27, is certified.
It is false that Lou, age 33, is certified.

Можно было бы попытаться использовать только запятой в качестве разделителя. Другими словами, вы можете попробовать следующее:

lineScanner.useDelimiter(",");

Это приведет к InputMismatchException. Это потому, что дополнительное пространство будет включено в знак того, что вы пытаетесь преобразовать в логические и пространства не совпадают ни с "истинным" или "ложь". Как и в случае со всеми приложениями регулярных выражений, основная власть требует, чтобы вы Уделите побольше внимания при построении вашей модели.

Для более подробной информации о сканере, см. официальную документацию.

Copyright (C) 2004-2005 Sun Microsystems, Inc
Все права защищены.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>