🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

1回答

631閲覧

フォルダ内のHTMLファイル限定の読み込みが出来なくなった。 正規表現での<title></title>のみの取得

Pro01x19

総合スコア17

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2021/02/25 03:40

編集2021/02/25 05:24

作りたいもの

特定のフォルダ(現在エディターの引数に設定済み)内のファイルの中からHTMLファイルのみを取得、
そのHTMLファイル名とファイル内の<title></title>の間にある要素を取得、
取得したファイル名、要素をプログラム実行の日時がわかるようなcsvファイルに記述する。

と言ったものを作りたいと思っております。!

基礎を固める段階にいると考えているのでライブラリの使用などは考えていません。

課題になっているもの

同じような質問を1度しているJava初学者です。

前回いただいたアドバイス大変勉強になりました。
その後、自分自身でコードを書き足していたのですが、

・前回まで出来ていたフォルダの中のHTMLファイルのみを読み込む。 が出来なくなってしまいました。

また前回に引き続きなのですが、
・HTMLファイル内のタイトルの取得が出来ず<title></title>があるファイルもタイトル無しと表記されてしまう。

という2つが問題になっています。
titleが取得できない原因は正規表現にあると思っています。前回ご回答いただいた方々のものも試してみたのですが上手くいきませんでした。

イメージ説明

現状こうなってしまっており、

最終的には

ファイル名 スペース タイトル 改行
ファイル名 スペース タイトル 改行

という形にしてみたいのですが、今はタイトルの取得のみを考えております。

該当のソースコード

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.regex.Pattern; import java.util.regex.Matcher; public class App { public static void main(String[] args) throws Exception { //カレンダークラスにより現在日時を取得 Calendar c = Calendar.getInstance(); // 日時のフォーマットを設定 DateFormat myFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss"); // ファイル名を定義 String FileName = "index" + myFormat.format(c.getTime()); // 場所を定義し、csvに拡張子を変更 File newFile = new File("/Users/mono/tmp/" + FileName + ".csv"); try{ if(newFile.createNewFile()){ System.out.println(FileName + "のファイルの作成に成功"); }else{ System.out.println("ファイルの作成に失敗"); } }catch(IOException e){ System.out.println(e); } // フォルダを指定 if (args.length != 0){ //引数必ず1つであること File dir = new File(args[0]); //設定からフォルダを引数として受け取る File[] fileList = dir.listFiles(); //フォルダの中身を配列として格納 if(fileList != null){ //もしフォルダの中身が終わってないなら for(int i = 0; i < fileList.length; i++){ //繰り返し処理をします try{ if (fileList[i].getName().contains(".html")){//もし html を含むファイル名があるならば if (checkBeforewritefile(newFile)){ // もしcsvファイルに書き込みをするならば BufferedWriter bw = new BufferedWriter(new FileWriter(newFile)); // csvファイルにファイル書き込みをする宣言 BufferedReader br = new BufferedReader(new FileReader(fileList[i])); // ファイルを読み込む準備 String line; // String型を定義 String regex = "<(title|title)>.*?</>"; // これを取得したいと定義 Pattern p = Pattern.compile(regex); // 定義した物をパターンと定義 while((line = br.readLine()) != null){ // 行がなくなるまで1行ずつ処理していく if (check(p,line)){ bw.write(line); }else{ bw.write("タイトル無し"); } } bw.write(fileList[i].getName()); //フォルダから取得したhtmlを含むファイル名をcsvファイルに書き込み System.out.println(fileList[i].getName() + "のファイル名を書き込みました"); bw.close(); } }else{ System.out.println("書き込めませんでした"); } }catch(IOException e){ System.out.println(e); }finally{ } } } } } private static boolean checkBeforewritefile(File newFile) { if(newFile.exists()){ if(newFile.isFile() && newFile.canWrite()){ return true; } } return false; } private static boolean check(Pattern p, String line) { Matcher m = p.matcher(line); if (m.find()){ return true; }else{ return false; } } }

試したこと

前回ご回答いただいた方々のコードやお言葉を参考にし、現在も模索中でございます。
HTMLファイルのみの取得に関しては繰り返しの処理に問題があると考え、順番を入れ替えるなどをしてみました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/02/25 04:45

fileList[i].getName() ↑これは何が取得されてるのでしょうか。デバッグで確認してください
Pro01x19

2021/02/25 04:56

m.ts10806さん、いつもありがとうございます。 デバッグしてみた所getNameが見当たりませんでした。 作成したcsvファイルにもファイル名がありませんでした。
m.ts10806

2021/02/25 05:02

それってそもそもエラーになるのでは。
Pro01x19

2021/02/25 05:11

失礼しました。 https://gyazo.com/f089390ce3e319b02e8488fdade466b4 このような形で取得は出来、書き込みが出来ているようです。質問にわかりやすく追記しておきます。 デバッグの結果なのですが、fileListは取得しており、その中には特定のフォルダ内のファイルが全て取得されており、pathにファイル名が記載されておりましたがNameという項目がありませんでした。
m.ts10806

2021/02/25 05:21

質問本文に画像添付できてないようです。投稿前にプレビュー確認を
Pro01x19

2021/02/25 05:25

失礼いたしました。添付し直しました。
dodox86

2021/02/25 07:02

前回回答したので今回はコメントのみとさせてもらいますが、デバッガーは使っているのですよね。「繰り返しの処理に問題があると考え、順番を入れ替えるなどをしてみました。」の文面をそのまま解釈すると、まず考えて、こういう(ああいう)動きにさせるようコーディングしているのではなく、コードをいじってみて希望の結果になるよう、トライアル&エラーなかんじで進めていませんか。よほど特殊なプログラムでない限り、まず頭の中で動きが完成しているのが先です。デバッガーは、その頭の中の設計が正しくコードに反映しているかを確認するために使います。 例えば > while((line = br.readLine()) != null){ > // 行がなくなるまで1行ずつ処理していく > if (check(p,line)){ > bw.write(line); > }else{ > bw.write("タイトル無し"); > } > } これで希望の出力が得られる見込みでしょうか。一行一行、更に広げてwhile文のループの中で希望の出力が得られるかまず頭の中で想像し、追いましょう。あまり横からコメントされても進めづらいと思いますので、この辺で。
Pro01x19

2021/02/26 00:54

dodox86さん、ありがとうございます。 質問後よく考えてみたのですが、正誤判定がprivateの物だけでは不十分ではないのかという仮説を立てboolean型を用いて実装することが出来ました。また、bw.close();が悪さをしているようだったので、定義元ともに場所を移動させた所上手く行きました!
dodox86

2021/02/26 01:13

まずは自力で解決できて何よりでした。おめでとうございます。
guest

回答1

0

自己解決

String line;
// String型を定義

String regex = "<title>.*?</title>"; // これを取得したいと定義 Pattern p = Pattern.compile(regex); // 定義した物をパターンと定義 boolean flg = true; // trueをflgに代入 while((line = br.readLine()) != null){ // 行がなくなるまで1行ずつ処理していく if (check(p,line)){ // もしlineにパターンがヒットするなら bw.write(line + enter); //そのlineを書き込みと改行 flg = false; // falseをflgに代入 break; } } if(flg){ // もしflgを処理するなら falseなら breakしないなら bw.write("タイトル無し" + enter); // タイトル無しを記述し改行 }

投稿2021/02/26 00:55

Pro01x19

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問