Java令牌和字串拆分


Java有一些實用程式類,可將一個字串分解成稱為令牌的部分。通過定義分隔符字元來定義被認為是令牌的字元序列。
StringTokenizer類位於java.util包中。StreamTokenizer類位於java.io包中。StringTokenizer將字串拆分成令牌,而StreamTokenizer是基於字元的流來存取令牌。

StringTokenizer

StringTokenizer物件根據對定界符的定義將字串拆分為令牌,它一次返回一個令牌。還可以隨時更改分隔符。可以通過指定字串並接受預設分隔符來建立一個StringTokenizer,它是空格,製表符,新行,回車符和換行符(「\t\n\r\f」) 如下:

StringTokenizer st  = new StringTokenizer("here is my string");

可在建立StringTokenizer時指定自己的分隔符,如下所示:下面的程式碼使用空格,逗號和分號作為分隔符。

String delimiters = " ,;";
StringTokenizer st  = new StringTokenizer("my text...",  delimiters);

可以使用hasMoreTokens()方法來檢查是否有更多的令牌,以及nextToken()方法從字串中獲取下一個令牌。

還可以使用String類的split()方法將字串基於分隔符拆分為令牌。split()方法接受正規表示式作為分隔符。

以下程式碼顯示如何使用StringTokenizerString類的split()方法。

import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) {
        String str = "This is a  test, this is another test.";
        String delimiters = "  ,"; // a space and a comma
        StringTokenizer st = new StringTokenizer(str, delimiters);

        System.out.println("Tokens  using a  StringTokenizer:");
        String token = null;
        while (st.hasMoreTokens()) {
            token = st.nextToken();
            System.out.println(token);
        }
    }
}

執行上面的程式碼,得到以下結果 -

Tokens  using a  StringTokenizer:
This
is
a
test
this
is
another
test.

StreamTokenizer

根據它們的型別來區分令牌,可使用StreamTokenizer類。

import static java.io.StreamTokenizer.TT_EOF;
import static java.io.StreamTokenizer.TT_NUMBER;
import static java.io.StreamTokenizer.TT_WORD;

import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;

public class Main {
  public static void main(String[] args) throws Exception {
    String str = "This is a  test, 200.89  which  is  simple 50";
    StringReader sr = new StringReader(str);
    StreamTokenizer st = new StreamTokenizer(sr);
    try {
      while (st.nextToken() != TT_EOF) {
        switch (st.ttype) {
        case TT_WORD: /* a word has been read */
          System.out.println("String value: " + st.sval);
          break;
        case TT_NUMBER: /* a number has been read */
          System.out.println("Number value:  " + st.nval);
          break;
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

上面的程式使用StringReader物件作為資料源。可以使用FileReader物件或任何其他Reader物件作為資料源。

重複呼叫StreamTokenizernextToken()方法。它填充StreamTokenizer物件的三個欄位:ttypesvalnvalttype欄位指示已讀取的令牌型別。

以下是型別(ttype)欄位的四個可能值:

欄位 含義
TT_EOF 已達到流的結尾。
TT_EOL 已達到行尾。
TT_WORD 單詞(字串)已從流中讀取為令牌。
TT_NUMBER 數位已從流中讀取為令牌。

如果ttype具有TT_WORD,則字串值儲存在其欄位sval中。如果返回TT_NUBMER,其數值儲存在nval欄位中。

上面的程式碼生成以下結果。

String value: This
String value: is
String value: a
String value: test
Number value:  200.89
String value: which
String value: is
String value: simple
Number value:  50.0