電子書籍の厳選無料作品が豊富!

趣味の延長でJavaの勉強を始めたプログラミング初心者です。
開発環境は All-In-One Eclipse 3.0.1 + PropertiesEditor を使用しています。

・やりたいこと
一つのフォルダに収められた、サイズが不定で、連番のファイル名が付けられた数百のHTMLファイルから、
外部ファイルに書いた正規表現を用いて複数の文字列を抜き出し、txtファイルにタブ区切りで書き込みたい。

・質問
1. 「不正なインデックスを使って配列がアクセスされたことを示し」ているエラーの解決方法を教えて頂きたいです。
  ソースコードの Pattern _d = Pattern.compile(_i); に正規表現を直接書くとエラーは出ませんが、
  抜き出した文字列がregexp.propertiesのキーの数だけ書き込まれてしまいます。
2. 対象のフォルダはzip形式で圧縮してありますが、解凍後のサイズは数百MBもあり、これを複数処理・保存する必要があります。
  そのためzip形式で圧縮したものに対して解凍せずに処理を行いたいのですが、その様な方法はあればご教示願います。

・ソースコードと外部ファイル
http://uploadr.net/file/c8f927ac3c
お手数ですがこちらをご覧下さい。

・エラー表示
Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 1
at java.util.regex.Matcher.group(Unknown Source)
at java.util.regex.Matcher.appendReplacement(Unknown Source)
at java.util.regex.Matcher.replaceAll(Unknown Source)
at goo.FileReadAndSearch.RaS(FileReadAndSearch.java:40)
at goo.FileReadAndSearch.main(FileReadAndSearch.java:13)


以上です。どうぞよろしくお願い致します。

A 回答 (2件)

補足有難うございます。


私が考えたのは、以下のようにパターンを16個用意すれば再利用できるのではないかな、ということでして。Try~Catchブロックの中だけ、以下に示します。



try {

Pattern _d[16];
for (int i=0; i<=15; i++) {
_d[i]=Pattern.compile(regexp_list[i]);
}

BufferedReader input = new BufferedReader(new FileReader("C:\\xxx\\abc_123.html"));
BufferedWriter output = new BufferedWriter(new FileWriter("C:\\xxx\\123.txt"));
String one_line;
while ((one_line = input.readLine()) != null) {
for (int i=0; i<regexp_list.length; i++) {
//------------//
//Pattern _d = Pattern.compile(regexp_list[i]);
//Matcher result_file = _d.matcher(one_line);
//-----------//
Matcher result_file = _d[i].matcher(one_line);
if (result_file.find()) {
String regexp_data = result_file.group(1);
System.out.print(regexp_data);
output.write(regexp_data +"\t");
}
}
}
input.close();
output.close();
} catch (IOException e) {
System.err.println(e);
System.exit(1);
}
    • good
    • 0
この回答へのお礼

ご教示いただき有難うございます。
配列を宣言するとき、型名にPatternを指定可能なことに気付いておりませんでした。
もっと初歩的な部分を勉強し直した方が良さそうですね。

上に示していただいたソースをそのまま貼り付けると「Patternを解決できません」と出ましたので、
「Pattern[16] _d」を「Pattern[] _d = new Pattern[regexp_list.length];」と書き換えることで、
動作はそのままに実行時間の短縮が出来ました。

質問の 1. は解決しましたし、 2. に取り掛かるには私の習熟具合ではまだ早いように感じますので、一度質問を締め切ります。
プログラミング歴5日の私ですが、osu_neko09さんのお陰でプログラムを書く楽しみの一片を味わえた気がします。
ここまでお付き合い下さり本当に有難うございました。

お礼日時:2009/11/17 00:12

以下の内容を補足いただけませんか?


・regexp_listの中身はなんでしょうか?「^<title>No\\.([0-9]+)</title>$」というような文字列が読み込まれているのでしょうか?

・38行目付近、「Pattern.compile(_i);」を「Pattern.compile(regexp_list[i]);」に書き換えてもエラーになりますか?

・40行目付近、「String regexp_data = result_file.replaceAll("$1");」を「String regexp_data = result_file.group(1);」に書き換えるとどうなりますか?

・やりたい処理は、読み込みファイルの各行から、No、名前、(中略)コメントを抜き出して、タブ区切りでファイルに出力することでしょうか?
でしたらパターンのコンパイルを、ループの外に追い出すほうが、処理が速くなると思いますが。

この回答への補足

・regexp_listの中身はなんでしょうか?
お察しの通り、regexp.propertiesの値が一行目から順に読み込まれていました。

・38行目付近、「Pattern.compile(_i);」を「Pattern.compile(regexp_list[i]);」に書き換えてもエラーになりますか?
エラーは解消し、regexp_listに格納した正規表現による検索とファイルへの書き出しに成功しました。

・40行目付近、「String regexp_data = result_file.replaceAll("$1");」を~
書き換え前後で出力された結果は変わりませんでした。
この場合、マッチした文字列を抜き出したいだけで、書き換える訳ではないので、replaceAllの使用は不適切ということですね。

・やりたい処理は、読み込みファイルの各行から、No、名前、(中略)コメントを抜き出して、タブ区切りでファイルに出力することでしょうか?
ひとつのHTMLファイルから抜き出した複数個のデータをタブ区切りで整形し一行にまとめ、data.txtへ出力したいと言うことでした。
また、HTMLファイルはマッチさせる必要の無い行が大半を占めています。言葉足らずの説明で失礼しました。
ソース内で指定したひとつのファイル(abc_123.html)に対して思う通りの処理を行えるようになったら、
for文なりlistFiles()なりを使ってフォルダ内の全ファイルに処理を掛けるようソースを書き換えるつもりです。

>でしたらパターンのコンパイルを、ループの外に追い出すほうが、処理が速くなると思いますが。
たしかに、今のままだとファイル数が増えるほど・マッチさせたい正規表現が増えるほど、無駄が多くなりますね。
tryの外かwhileの外に出すと解釈し2時間ほど試行錯誤しましたが、どのように書けばエラーを出さずに済むかが分かりませんでした。

ご指摘頂いた箇所を手直ししたことで、ひとまずは満足の行く結果が得られました。有難うございます。
もし宜しければ、パターンのコンパイルに関してのヒントも頂けると助かります。

質問時に上げたものに上記の修正点を書き換えたソースコード
http://uploadr.net/file/4179241ad2

補足日時:2009/11/16 18:12
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!