Java StreamTokenizer 类
最后修改时间:2025 年 4 月 16 日
java.io.StreamTokenizer
类将输入流解析成标记。它可以识别数字、带引号的字符串和各种注释风格。这个类对于简单的词法分析任务很有用。
StreamTokenizer
将输入分解成标记,这些标记可以是单词、数字、字符串或特殊字符。它提供了配置哪些应被视为空白、注释或单词字符的方法。该类不是线程安全的。
StreamTokenizer 类概述
StreamTokenizer
将 InputStream
或 Reader
作为输入。它将标记分类为 TT_WORD
、TT_NUMBER
或 TT_EOF
等类型。该类提供了配置标记识别规则的方法。
public class StreamTokenizer { public StreamTokenizer(InputStream in); public StreamTokenizer(Reader r); public void resetSyntax(); public void wordChars(int low, int hi); public void whitespaceChars(int low, int hi); public void ordinaryChars(int low, int hi); public void ordinaryChar(int ch); public void commentChar(int ch); public void quoteChar(int ch); public void parseNumbers(); public void eolIsSignificant(boolean flag); public void slashStarComments(boolean flag); public void slashSlashComments(boolean flag); public void lowerCaseMode(boolean fl); public int nextToken(); public int ttype; public String sval; public double nval; public int lineno(); }
上面的代码展示了 StreamTokenizer
的关键方法和字段。nextToken
方法读取下一个标记。标记类型存储在 ttype
中,字符串和数值存储在 sval
和 nval
中。
创建 StreamTokenizer
StreamTokenizer 可以从 InputStream 或 Reader 创建。 Reader 版本更适合字符流处理。在使用之前,该类需要配置才能定义标记识别规则。
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.StreamTokenizer; public class Main { public static void main(String[] args) { try { // Create from Reader BufferedReader reader = new BufferedReader(new FileReader("data.txt")); StreamTokenizer tokenizer1 = new StreamTokenizer(reader); // Basic configuration tokenizer1.wordChars('a', 'z'); tokenizer1.wordChars('A', 'Z'); tokenizer1.whitespaceChars(' ', ' '); tokenizer1.whitespaceChars('\n', '\n'); tokenizer1.whitespaceChars('\r', '\r'); tokenizer1.whitespaceChars('\t', '\t'); System.out.println("StreamTokenizer created and configured"); reader.close(); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了如何从 Reader 创建 StreamTokenizer。我们将其配置为将字母识别为单词字符和常见的空白字符。完成后,始终关闭底层流。配置是标记化的必要条件。
基本标记化示例
StreamTokenizer 的最简单用法是读取标记,直到文件结束。每次调用 nextToken
都会返回标记类型。标记值存储在 sval
(对于单词)或 nval
(对于数字)中。
import java.io.StringReader; import java.io.StreamTokenizer; public class Main { public static void main(String[] args) { String input = "Hello 123 World 45.67"; StringReader reader = new StringReader(input); StreamTokenizer tokenizer = new StreamTokenizer(reader); try { tokenizer.parseNumbers(); while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { switch (tokenizer.ttype) { case StreamTokenizer.TT_WORD: System.out.println("Word: " + tokenizer.sval); break; case StreamTokenizer.TT_NUMBER: System.out.println("Number: " + tokenizer.nval); break; default: System.out.println("Other: " + (char) tokenizer.ttype); } } } catch (Exception e) { e.printStackTrace(); } } }
此示例将包含单词和数字的简单字符串进行标记化。parseNumbers
方法启用数字识别。 switch 语句处理不同的标记类型。TT_EOF 表示输入流结束。
处理带引号的字符串
当使用 quoteChar
配置时,StreamTokenizer 可以识别带引号的字符串。整个带引号的字符串成为一个单独的标记。单引号和双引号都可以配置为引号字符。
import java.io.StringReader; import java.io.StreamTokenizer; public class Main { public static void main(String[] args) { String input = "Name 'John Doe' Age 25 City \"New York\""; StringReader reader = new StringReader(input); StreamTokenizer tokenizer = new StreamTokenizer(reader); try { // Configure single and double quotes as quote characters tokenizer.quoteChar('\''); tokenizer.quoteChar('"'); while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { if (tokenizer.ttype == '\'' || tokenizer.ttype == '"') { System.out.println("Quoted string: " + tokenizer.sval); } else if (tokenizer.ttype == StreamTokenizer.TT_WORD) { System.out.println("Word: " + tokenizer.sval); } else if (tokenizer.ttype == StreamTokenizer.TT_NUMBER) { System.out.println("Number: " + tokenizer.nval); } } } catch (Exception e) { e.printStackTrace(); } } }
此示例演示了处理单引号和双引号字符串。带引号的内容可在 sval
中找到。引号字符本身作为标记类型返回。这允许区分不同的引号样式。
自定义标记识别
StreamTokenizer 提供了广泛的自定义,以确定构成标记的内容。您可以将字符范围定义为单词字符、空白或普通字符。resetSyntax
方法清除所有先前的设置。
import java.io.StringReader; import java.io.StreamTokenizer; public class Main { public static void main(String[] args) { String input = "user@example.com 192.168.1.1 #comment"; StringReader reader = new StringReader(input); StreamTokenizer tokenizer = new StreamTokenizer(reader); try { // Reset and customize syntax tokenizer.resetSyntax(); tokenizer.wordChars('a', 'z'); tokenizer.wordChars('A', 'Z'); tokenizer.wordChars('0', '9'); tokenizer.wordChars('@', '@'); tokenizer.wordChars('.', '.'); tokenizer.whitespaceChars(' ', ' '); tokenizer.commentChar('#'); while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { if (tokenizer.ttype == StreamTokenizer.TT_WORD) { System.out.println("Token: " + tokenizer.sval); } } } catch (Exception e) { e.printStackTrace(); } } }
此示例展示了自定义语法配置。我们将“@”和“.”作为单词字符来处理电子邮件和 IP。 “#”是注释字符。在 resetSyntax
之后,所有字符都是“普通字符”,直到配置为止。
跟踪行号
StreamTokenizer 可以在解析期间跟踪行号。lineno
方法返回当前的行号。这对于源代码处理中的错误报告很有用。
import java.io.StringReader; import java.io.StreamTokenizer; public class Main { public static void main(String[] args) { String input = "First line\nSecond line\nThird line"; StringReader reader = new StringReader(input); StreamTokenizer tokenizer = new StreamTokenizer(reader); try { tokenizer.eolIsSignificant(true); while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { if (tokenizer.ttype == StreamTokenizer.TT_EOL) { System.out.println("End of line " + tokenizer.lineno()); } else if (tokenizer.ttype == StreamTokenizer.TT_WORD) { System.out.println("Word at line " + tokenizer.lineno() + ": " + tokenizer.sval); } } } catch (Exception e) { e.printStackTrace(); } } }
此示例演示了行号跟踪。eolIsSignificant(true)
使行尾标记具有意义。lineno
方法有助于识别标记位置。这对于编译器或解析器实现很有价值。
处理注释
StreamTokenizer 支持 C 风格(/* */)和 C++ 风格(//)的注释。slashStarComments
和 slashSlashComments
方法控制此行为。注释内容在标记化期间被跳过。
import java.io.StringReader; import java.io.StreamTokenizer; public class Main { public static void main(String[] args) { String input = "code /* comment */ more // line comment\nend"; StringReader reader = new StringReader(input); StreamTokenizer tokenizer = new StreamTokenizer(reader); try { tokenizer.slashStarComments(true); tokenizer.slashSlashComments(true); while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { if (tokenizer.ttype == StreamTokenizer.TT_WORD) { System.out.println("Token: " + tokenizer.sval); } else if (tokenizer.ttype == StreamTokenizer.TT_EOL) { System.out.println("End of line"); } } } catch (Exception e) { e.printStackTrace(); } } }
此示例展示了 StreamTokenizer 中的注释处理。两种注释样式都被启用。标记器自动跳过注释内容。只有非注释标记由 nextToken
返回。
来源
在本文中,我们介绍了 Java StreamTokenizer 类的基本方法和特性。理解这些概念对于 Java 应用程序中的文本解析和词法分析至关重要。
作者
列出所有Java教程。