StringTokenizer类是Java提供的一种方便的字符串分解器,它的原理是根据分隔符把字符串分解为一个个的标记(Token),然后按照请求返回各个标记。这个过程称为Tokenization,实际上就是把字符序列转换成应用程序能够理解的多个标记。
StringTokenizer类有以下3种构造函数:
StringTokenizer(String str);
用一个指定的字符串构造一个StringTokenizer。
StringTokenizer(String str, String delim);
用一个指定的字符串构造一个StringTokenizer,并指定分隔符。
StringTokenizer(String str, String delim, boolean returnDelims);
用一个指定的字符串构造一个StringTokenizer,并指定分隔符,并指定是否将分隔符作为标记(Token)。
StringTokenizer类的常用方法有以下几种。
String nextToken(String delim);
利用分隔符delim,返回下一个标记(Token)。
String nextToken();
返回StringTokenizer中的下一个标记(Token)。
Object nextElement();
返回结果与nextToken( )方法一样,但它的类型是Object。
int countTokens();
返回字符串可以被分隔成标记(Token)的个数。
【例5-9】本例程序提供两个方法,一个removeComment( )方法去掉字符串中以“:”开头的行,另一个addBr( )方法将回车符“\n”用HTML里面的换行标记“<br>”替换。
//~TestStringTokenizer.java
import java.util.*;
import java.io.*;
public class TestStringTokenizer {
public TestStringTokenizer() {}
public static void main(String[] args) {
TestStringTokenizer tst = new TestStringTokenizer();
String str = "begin \n:startup \n add a b \n:calculation \nend \n:stop";
//初始字符串
String strnew1 = tst.RemoveComment(str);
//去掉“:”开头的行
String strnew2 = tst.addBr(strnew1);
//将回车符换成“<br>”
System.out.println("The original string is: \n" + str);
//打印初始字符串
System.out.println("The string after removeComment is: \n" + strnew1);
//打印去掉“:”开头的行之后的字符串
System.out.println("The string after Content is: \n" + strnew2);
//打印回车换成<br>之后的字符串
}
//去掉其中以“:”开头的注释行
public String RemoveComment(String Content){
String makeContent=new String();
StringTokenizer strToken=new StringTokenizer(Content,"\n");
//以回车符分开各行为token
String tempToken=null;
while(strToken.hasMoreTokens()){
tempToken=strToken.nextToken();
if(tempToken.indexOf(':')!=0)
makeContent=makeContent+tempToken+"\n";
//如果首字符不是“:”,加入makeContent内容中
}
return makeContent;
}
//将“\n”转成“<br>”返回新的字符串
public String addBr(String Content){
String makeContent=new String();
StringTokenizer strToken=new StringTokenizer(Content,"\n");
while(strToken.hasMoreTokens()){
makeContent=makeContent + strToken.nextToken() + "<br>";
//在各个token之后加入“<br>”
}
return makeContent;
}
}
运行结果如下:
The original string is:
begin
:startup
add a b
:calculation
end
:stop
The string after removeComment is:
begin
add a b
end
The string after Content is:
begin <br> add a b <br>end <br>
虽然StringTokenizer类用起来很方便,但它的功能却很有限。这个类只是简单地在输入字符串中查找分隔符,一旦找到了分隔符就分割字符串。它不会检查分隔符是否在子串之中这类条件,当输入字符串中出现两个连续的分隔符时,它也不会返回""(字符串长度为0)形式的标记。
我们再回头分析一下StringTokenizer类的3个构造方法和它们的局限。
StringTokenizer(String sInput):以空白字符(“”,“\t”,“\n”)为分隔符分割字符串。
StringTokenizer(String sInput, String sDelimiter):以sDelimiter为分隔符分割字符串。
StringTokenizer(String sInput, String sDelimiter, boolean bReturnTokens):以sDelimiter为分隔符分割字符串,但如果bReturnTokens为true,则分隔符也作为标记返回。
第一个构造函数不检查输入字符串是否包含子串。例如,如果以空白字符为分隔符分割字符串"hello. Today \"I am \" going to my home town",则字符串分解结果是hello.、Today、"I、am、"、going等,而不是hello.、Today、"I am "、going等。
第二个构造函数不检查两个分隔符连续出现的情况。例如,如果以“,”为分隔符分割"book, author, publication,,,date published"这个字符串,则StringTokenizer返回book、author、publication和date published这4个标记,而不是book、author、publication、""、""和date published这6个标记(其中""表示0长度字符串)。要得到6个标记的答案,必须把StringTokenizer的bReturnTokens参数设置为true。
为了突破这些局限,Java 2平台提供了BreakIterator类,它是在StringTokenizer类之上改进的字符串分解器。
BreakIterator类位于java.text.*包中,适合于文本分析的操作,用于获取文本中的个体信息,比如字符、单词、句子以及整行等。
BreakIterator的主要方法如下:
· void setText(String newText)设置BreakIterator类中的文本为newText。
· current( )、first( )、next( )、last( )、previous( )这些方法分别返回文本中当前边界(boundary),第一边界,下一个边界,最后一个边界,之前边界的数值。
· isBoundary(int offset) 判断offset是否处在一个边界上。
【例5-10】程序示例。
//~TestBreakIterator.java
import java.text.*;
import java.util.Locale;
public class TestBreakIterator {
public TestBreakIterator() {}
public static void main(String[] args) {
if (args.length == 1) {
String stringToExamine = args[0];
//print each word in order
BreakIterator boundary = BreakIterator.getWordInstance();
boundary.setText(stringToExamine);
printEachForward(boundary, stringToExamine);
//print each sentence in reverse order
boundary = BreakIterator.getSentenceInstance(Locale.US);
boundary.setText(stringToExamine);
printEachBackward(boundary, stringToExamine);
printFirst(boundary, stringToExamine);
printLast(boundary, stringToExamine);
}
}
public static void printEachForward(BreakIterator boundary, String source) {
int start = boundary.first();
for (int end = boundary.next();
end != BreakIterator.DONE;
start = end, end = boundary.next()) {
System.out.println(source.substring(start,end));
}
}
public static void printEachBackward(BreakIterator boundary, String source) {
int end = boundary.last();
for (int start = boundary.previous();
start != BreakIterator.DONE;
end = start, start = boundary.previous()) {
System.out.println(source.substring(start,end));
}
}
public static void printFirst(BreakIterator boundary, String source) {
int start = boundary.first();
int end = boundary.next();
System.out.println(source.substring(start,end));
}
public static void printLast(BreakIterator boundary, String source) {
int end = boundary.last();
int start = boundary.previous();
System.out.println(source.substring(start,end));
}
public static void printAt(BreakIterator boundary, int pos, String source)
{
int end = boundary.following(pos);
int start = boundary.previous();
System.out.println(source.substring(start,end));
}
}
执行程序,这里要在Java命令后加参数,在命令行下输入如下语句。
java TestBreakIterator "This is an apple, That is a boy."
输出结果如下:
This
is
an
apple
,
That
is
a
boy
.
This is an apple, That is a boy.
This is an apple, That is a boy.
This is an apple, That is a boy.