私がやろうとしているのは、.Javaファイルを読み取り、すべての識別子を取り出してリストに保存することです。私の問題は.split()メソッドにあります。このコードをそのまま実行すると、ArrayOutOfBoundsが取得されますが、区切り文字を「。」から変更するとそれ以外の場合、コードは機能します。しかし、「。」で解析された行が必要です。だから私はこれを達成できる別の方法がありますか?
import Java.io.BufferedReader;
import Java.io.FileNotFoundException;
import Java.io.FileReader;
import Java.io.IOException;
import Java.util.*;
public class MyHash {
private static String[] reserved = new String[100];
private static List list = new LinkedList();
private static List list2 = new LinkedList();
public static void main (String args[]){
Hashtable hashtable = new Hashtable(997);
makeReserved();
readFile();
String line;
ListIterator itr = list.listIterator();
int listIndex = 0;
while (listIndex < list.size()) {
if (itr.hasNext()){
line = itr.next().toString();
//PROBLEM IS HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
String[] words = line.split("."); //CHANGE THIS AND IT WILL WORK
System.out.println(words[0]); //TESTING TO SEE IF IT WORKED
}
listIndex++;
}
}
public static void readFile() {
String text;
String[] words;
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("MyHash.Java")); //NAME OF INPUT FILE
} catch (FileNotFoundException ex) {
Logger.getLogger(MyHash.class.getName()).log(Level.SEVERE, null, ex);
}
try {
while ((text = in.readLine()) != null){
text = text.trim();
words = text.split("\\s+");
for (int i = 0; i < words.length; i++){
list.add(words[i]);
}
for (int j = 0; j < reserved.length; j++){
if (list.contains(reserved[j])){
list.remove(reserved[j]);
}
}
}
} catch (IOException ex) {
Logger.getLogger(MyHash.class.getName()).log(Level.SEVERE, null, ex);
}
try {
in.close();
} catch (IOException ex) {
Logger.getLogger(MyHash.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static int keyIt (int x) {
int key = x % 997;
return key;
}
public static int horner (String Word){
int length = Word.length();
char[] letters = new char[length];
for (int i = 0; i < length; i++){
letters[i]=Word.charAt(i);
}
char[] alphabet = new char[26];
String abc = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < 26; i++){
alphabet[i]=abc.charAt(i);
}
int[] numbers = new int[length];
int place = 0;
for (int i = 0; i < length; i++){
for (int j = 0; j < 26; j++){
if (alphabet[j]==letters[i]){
numbers[place]=j+1;
place++;
}
}
}
int hornered = numbers[0] * 32;
for (int i = 1; i < numbers.length; i++){
hornered += numbers[i];
if (i == numbers.length -1){
return hornered;
}
hornered = hornered % 997;
hornered *= 32;
}
return hornered;
}
public static String[] makeReserved (){
reserved[0] = "abstract";
reserved[1] = "assert";
reserved[2] = "boolean";
reserved[3] = "break";
reserved[4] = "byte";
reserved[5] = "case";
reserved[6] = "catch";
reserved[7] = "char";
reserved[8] = "class";
reserved[9] = "const";
reserved[10] = "continue";
reserved[11] = "default";
reserved[12] = "do";
reserved[13] = "double";
reserved[14] = "else";
reserved[15] = "enum";
reserved[16] = "extends";
reserved[17] = "false";
reserved[18] = "final";
reserved[19] = "finally";
reserved[20] = "float";
reserved[21] = "for";
reserved[22] = "goto";
reserved[23] = "if";
reserved[24] = "implements";
reserved[25] = "import";
reserved[26] = "instanceof";
reserved[27] = "int";
reserved[28] = "interface";
reserved[29] = "long";
reserved[30] = "native";
reserved[31] = "new";
reserved[32] = "null";
reserved[33] = "package";
reserved[34] = "private";
reserved[35] = "protected";
reserved[36] = "public";
reserved[37] = "return";
reserved[38] = "short";
reserved[39] = "static";
reserved[40] = "strictfp";
reserved[41] = "super";
reserved[42] = "switch";
reserved[43] = "synchronize";
reserved[44] = "this";
reserved[45] = "throw";
reserved[46] = "throws";
reserved[47] = "trasient";
reserved[48] = "true";
reserved[49] = "try";
reserved[50] = "void";
reserved[51] = "volatile";
reserved[52] = "while";
reserved[53] = "=";
reserved[54] = "==";
reserved[55] = "!=";
reserved[56] = "+";
reserved[57] = "-";
reserved[58] = "*";
reserved[59] = "/";
reserved[60] = "{";
reserved[61] = "}";
return reserved;
}
}
String.split
は正規表現を取り、「。」正規表現には特別な意味があります。
あなたは(おそらく)次のようなものが欲しいです:
String[] words = line.split("\\.");
一部の人々はこれを機能させるのに苦労しているようです。そこで、正しい動作を検証するために使用できる実行可能なコードを以下に示します。
import Java.util.Arrays;
public class TestSplit {
public static void main(String[] args) {
String line = "aa.bb.cc.dd";
String[] words = line.split("\\.");
System.out.println(Arrays.toString(words));
// Output is "[aa, bb, cc, dd]"
}
}
文字列リテラル区切り文字で分割する場合、最も安全な方法は Pattern.quote() メソッドを使用することです:
_String[] words = line.split(Pattern.quote("."));
_
他の回答で説明されているように、_"\\."
_での分割は正しいですが、quote()
はこれをエスケープします。
Splitの引数は正規表現です。ピリオドは、すべてに一致する正規表現のメタ文字です。したがって、line
のすべての文字は分割文字と見なされ、破棄されます。また、それらの間の空の文字列はすべて破棄されます空の文字列)。その結果、何も残っていません。
ピリオドをエスケープする場合(エスケープされた円記号をその前に追加することにより)、リテラルのピリオドに一致させることができます。 (line.split("\\.")
)
ドットをエスケープしてみましたか?このような:
String[] words = line.split("\\.");
これは間違いなくこれを行う最良の方法ですが、次のようなことをすることで完了しました。
String imageName = "my_image.png";
String replace = imageName.replace('.','~');
String[] split = replace.split("~");
System.out.println("Image name : " + split[0]);
System.out.println("Image extension : " + split[1]);
出力、
Image name : my_image
Image extension : png
Splitの引数は正規表現です。 「。」何にでもマッチするため、分割する区切り文字は何でもかまいません。
パフォーマンスが問題になる場合は、StringTokenizer
の代わりにsplit
の使用を検討する必要があります。 StringTokenizer
は、「レガシー」クラスであるにもかかわらず、split
よりもはるかに高速です(非推奨ではありません)。
StringTokenizer クラスに興味があるかもしれません。ただし、Javaのドキュメントでは、StringTokenizerがレガシークラスであるため、.splitメソッドを使用することを推奨しています。