📝

Pythonの標準ライブラリであるreを使ったHTML文書からのHTMLタグの消去

2023/09/20に公開4

この記事はQiitaの記事の転載です!!

Qiitaの記事はこちら!!

https://qiita.com/blueman/items/b8b9bc29c9e059b30517


目次

はじめに
作成した経緯
実行環境
テキストファイル生成時の日付の取得方法
テキストファイルのパスの設定方法
メインウィンドウのサイズの設定方法
メインウィンドウのタイトルの設定方法
テキストボックスの作成方法
テキストボックスの位置の設定方法
テキストボックスからの文字列の取得方法
取得した文字列からHTMLタグを削除する方法
テキストボックスのデータをテキストファイルに書き込む方法
文字列の末尾の改行を削除する方法
ソースコード
結果
まとめ

はじめに

今回は、前回のTwitter(X)のアンケートでトップだったファイル操作についての記事です。
そのジャンルの中から、HTML で書かれた文字列から HTML タグを取り除いて Windows のメモ帳に HTML タグのない文章を書き込む
(テキストファイル名には、生成時の日付が入っている)プログラムを作成したのでそれについて紹介したいと思います。


マイページについて

https://qiita.com/blueman

X(Twitter)について

https://twitter.com/blueman_info

Qiitaについて

作成した経緯

QiitaZenn で記事を投稿しているときにある問題に直面しました!!

  • 直面した問題

Qiita では、HTML のタグが使えるが、 Zenn では、HTML のタグが使えない
(一部例外あり( <br> とか))


そんな時にこんなアイデアを思いつきました!!

思いついたアイデア

Qiita で作成した記事の HTML タグのみを削除し、その文字列を Zenn で投稿すればよいのではないか🤔

このアイデアをもとに今回紹介する HTML のタグを削除するプログラムを作成しました!!

実行環境

実行環境は次の通りです。

実行環境
  • 環境
    • Windows10
    • Python 3.10.5

:::note info
tkinterre は、標準ライブラリなので特に気にしなくても大丈夫です!!

:::

処理内容ライブラリの対応を分かりやすく表にすると次の通りです。

説明
処理内容 モジュールライブラリ
テキストボックスの作成 tkinter
正規表現による文字列の操作
(文字列から特定の文字列を削除)
re

テキストファイル生成時の日付の取得方法

こちらのソース

https://note.nkmk.me/python-datetime-now-today/#datetime-datetimedatetimenow

によると、datetime.now() を使うことで現在日時を取得できるそうです。
この方法でプログラム実行時の日付を取得しました。

ファイル生成時の日付を取得する手順は次の通りです!!

取得手順

プログラムを実行すると、

  1. datetime.now() が走る
  2. 現在日時(プログラム実行時の日時)を取得(この処理で取得された日時がファイル生成時の日時となります)

月のデータへのアクセス方法

datetime.now() で取得されたデータの month にアクセスすることで月のデータを取得しました。

日のデータへのアクセス方法

datetime.now() で取得されたデータの day にアクセスすることで日のデータを取得しました。

テキストファイルのパスの設定方法

次の手順でテキストファイルのパスを設定しました。

手順
  1. テキストファイル生成時の日付の取得方法で取得した日付を文字列( str 型)に型変換
  2. ./変換後文章1. で型変換した文字列.txt を結合

メインウィンドウのサイズの設定方法

前回の記事をもとに設定しました!!

メインウィンドウのタイトルの設定方法

こちらのソース

https://little-movie.com/window-title/

によると、title メソッドを使うことでメインウィンドウのタイトルを設定できるそうです。
このメソッドを使って、メインウィンドウのタイトルを設定しました。

テキストボックスの作成方法

こちらのソース

https://kuroro.blog/python/bK6fWsP9LMqmER1CBz9E/

によると、Text ウィジェットを使うことで tkinterテキストボックスを作成できるそうです。
このウィジェットを使って、テキストボックスを作成しました。

テキストボックスの位置の設定方法

こちらのソース

https://daeudaeu.com/tkinter_place/#place

によると、place メソッドを使うことで指定した座標上にウィジェットを配置できるそうです。

また、こちらのソース

https://daeudaeu.com/tkinter_place/#place-2

によると、place メソッドの原点は左上端にあるそうです。

また、こちらのソース

https://daeudaeu.com/tkinter_place/#place-x-y

によると、place メソッドの xy という引数でウィジェットを配置する座標を指定できるそうです。

また、こちらのソース

https://daeudaeu.com/tkinter_place/#place-width-height

によると、place メソッドの width という引数でウィジェットの幅height という引数でウィジェットの高さを指定できるそうです。

テキストボックスからの文字列の取得方法

こちらのソース

https://ossa2019.stars.ne.jp/Remember/tkinter/tk6.html#i6-2

によると、get() を使うことでテキスト( Text ウィジェットのこと)から文字列を取得できるそうです。また、get()

  • 第1引数文字列取得の開始位置
  • 第2引数文字列取得の終了位置

を設定できるそうです。
これらの方法で、テキストボックスの文字列を取得しました。

取得した文字列からHTMLタグを削除する方法

テキストボックスからの文字列の取得方法文字列を取得できました。
以降は、取得された文字列をもとに処理を実行していきます。

こちらのソース

https://note.nkmk.me/python-re-match-search-findall-etc/#sub-subn

によると、re モジュールの sub() を使うことで正規表現を使った文字列の置換ができるそうです。
この方法を使って、文字列のHTMLタグを空文字に置換することで文字列からHTMLタグを削除しました。(空文字とは、長さが0の文字列のことです)

正規表現について詳しくは下のリンクより

https://qiita.com/hayate242/items/7106977b6460c5120fb4#正規表現早見表

使用したものリスト

今回は、この早見表の中から

  • \w
  • *
  • |
  • \s
  • \

を使いました。

テキストボックスのデータをテキストファイルに書き込む方法

こちらのソース

https://rait-09-kts.hatenablog.jp/entry/2021/07/04/212916

によると、ウィジェット名.bind('<Return>',関数名) とすることでエンターキーの入力により関数を実行できるそうです。
この方法を使って、エンターキーを用いてテキストボックスのデータをテキストファイルに送信するための関数を実行させました。

また、こちらのソース

https://note.nkmk.me/python-file-io-open-with/

によると、次の手順でテキストファイルへの書き込みができるそうです。

書き込みの手順は次の通りだそうです。

  1. open() を使うことでファイルを開く。
  2. ファイルオブジェクトの write() メソッドで書き込む。
補足

文字列の末尾の改行を削除する方法

テキストボックスのデータをテキストファイルに書き込む方法エンターキーをキーイベントとして取得させました。この方法だと、エンターキーが押されたときに改行されたと認識してしまい文字列の末尾に余計な改行が入ってしまいました。

こちらのソース

https://python-jp.dev/articles/2079

によると、rstrip() メソッドを使うことで文字列の末尾の改行を削除できるそうです。
このメソッドを使うことで、文字列の末尾の改行を削除しました。

ソースコード

下にソースコードを示します。おそらく実行環境で示した環境では動くはず。

ソースコード
text_trans.py
import tkinter as tk                                                #テキストボックス作成(文字列の受け取り)
import re                                                           #正規表現での文字列操作
import datetime

now = datetime.datetime.now()                                                   #テキストファイル生成時の日付を取得

path = './変換後文章'+'('+str(now.year)+'_'+str(now.month)+'_'+str(now.day)+')'+'.txt'  #テキスト形式の指定

root = tk.Tk()                                                      #tkinterの初期化
root.geometry('300x300')                                            #tkinterで作ったGUI(rootの画面のサイズ指定)
root.title('文字列変換')                                            #GUIのタイトルの設定

def func(event):                                                    #GUIの関数定義
	text = entry.get(0.,tk.END)                                   #テキストボックスからの文字列の取得(第1引数は何文字目から開始するか(今回は、1文字目からなので"1.0"と指定)第2引数は
	                                                                #何文字目まで取得するか(今回は、最後までなので"end"と指定))
	text_trans = re.sub(r"<\w*>|</\w*>|<\w*\s\w*=\"\w*\">",'',text) #正規表現で文字列からで囲まれた文字列とが含まれている文字列を削除(第1引数で正規表現で指定、第2引数で置き換える文字列、第3引数で対象の文字列を指定)
	with open(path,mode='w') as file:                               #fileという名前で書き込みモード('w')のpath('./text.txt')を開く
		file.write(text_trans.rstrip())                             #text_transの文字列をpathのファイル(変換後文章.txt)に書き込む
	print("変換後:",text_trans)                                     #動作確認用(text_transの文字列をコマンドプロンプト上に出力)

entry = tk.Text()                                                   #テキストボックスの設定
entry.place(x=0,y=0,width=300,height=300)                           #テキストボックスをどの位置にどのくらいの大きさで表示するかを設定(第1引数にx座標(今回は、一番上なので0を指定)、
                                                                    #第2引数にy座標(今回は、一番上なので0を指定)、第3引数に幅(今回は、画面いっぱいに表示させたいのでgeometryで設定した値と
                                                                    #同値)、第4引数に高さ(今回は、画面いっぱいに表示させたいのでgeometryで設定した値と同値)

entry.bind('',func)                                         #エンターキーが押される(キーイベントが''となる)と処理(funcの中身)を実行

root.mainloop()                                                     #GUIの表示(この処理がないと一瞬表示されて消えるので表示されていないように見える)

結果

下に結果を示します。
こちらの記事で実行しました。(記事の内容が短く実行結果が分かりやすいのでこちらにしました)

https://qiita.com/blueman/items/542064585cd44f894494

こちらのGUIに入力します。

入力用GUI

文字列変換_テキストボックス.JPG

確認用のCUI(コマンドプロンプト上での表示結果)は次の通りです。

確認用CUI

実行結果_CUI.JPG
実行結果_CUI_2.JPG
実行結果_CUI_3.JPG
実行結果_CUI_4.JPG
実行結果_CUI_5.JPG
実行結果_CUI_6.JPG
実行結果_CUI_7.JPG
実行結果_CUI_8.JPG

テキストファイルの存在確認

テキストファイル.JPG

この様にテキストファイルがデスクトップ上に生成されます。

テキストファイルの中身

テキストファイル_中身.JPG
テキストファイル_中身_2.JPG
テキストファイル_中身_3.JPG
テキストファイル_中身_4.JPG
テキストファイル_中身_5.JPG
テキストファイル_中身_6.JPG
テキストファイル_中身_7.JPG
テキストファイル_中身_8.JPG

実行結果を見ると、<img src=...> の部分が削除されていないことが分かります。しかし、この HTML タグは画像挿入HTML タグであり Qiita の画像挿入の Markdown 記法である ![..](..)Zenn でも使えるので問題ないです。
今後は、![..](..) を使って画像挿入をしていこうと思います。

まとめ

今回は、前回のTwitter(X)のアンケートでトップだったファイル操作から HTML で書かれた文字列から HTML タグを取り除いて Windows のメモ帳に HTMLタグのない文章を書き込む(テキストファイル名には、生成時の日付が入っている)プログラムを紹介しました。(一部の HTML タグが削除できませんでした。申し訳ございませんでした。🙇‍♂️)
この記事が実際に役に立つかどうかは分かりませんが、誰かの役に立ってくれると嬉しいです。😀
記事を執筆する余力があれば、次回も記事を投稿する予定です。
次回の予定としては、今回のTwitter(X)のアンケートでトップだった動画像処理から OpenCVカスケード型分類器の一つである Haar CascadeHaar-like 特徴量dlibを使ったPythonの顔認証ライブラリのFace RecognitionHoG 特徴量を使い、それぞれの特徴量について顔認識をさせ認識結果から顔の部分に画像を埋め込むプログラムができたのでそれに関する記事を投稿予定です!!
(特徴の部分で「少しだけ Haar-like 特徴量HoG 特徴量違いについても簡単に紹介できればな😀」と思います!!)

Discussion

yKesamaruyKesamaru

素晴らしい記事をありがとうございます😃!

HTLMのマークアップを全て正規表現で取り除く、古のPerlの記憶が蘇ってきました(笑)。

OpenCVのimshow()問題は、なかなか根深いですよね。
うちも以下のような記事を出したことがあります。
https://zenn.dev/ykesamaru/articles/4b2d6f775d98e4

今の所、

  • 仮想環境にopencv-pythonをインストール
  • 仮想環境からopencv-pythonをアンインストール
  • システムのパスをコードに追加して、import cv2

この手順でうまく行っています。この方法のために、システムにopencv-python3を入れました。
なぜかはよく分かっていませんが、この作業をするときちんと動作してくれます。。

ブルーマンブルーマン

記事のコメントと記事をほめていただきありがとうございます

yKesamaruさんは、 Perl もやってらっしゃったんですね

僕の場合は、

  1. pip uninstallpip で管理されているパッケージを全てアンインストール
  2. 必要なパッケージだけを pip install でインストール

cv2.imshow() が正常に動作するようになりました

今後、 PythonOpenCV 関連で調べても分からないエラーが発生した時にはyKesamaruさんにお伺いしてもよろしいでしょうか?