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

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

詳細はこちら
正規表現

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1446閲覧

【Python】テキストデータを辞書型やリスト型に変換したい

t.z

総合スコア21

正規表現

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/12/12 17:45

タイトルにある通り、テキストデータを辞書型やリスト型に変換したいです。
目的はデータ解析と、自分の作業の効率化のためです。
よろしくお願いします。

#主題1

オフラインにあるhtmlデータをpythonの辞書型に落とし込みたいです。スクレイピングではなく、もう少し小規模なものを考えています。ページのソースを表示してコピペできるくらいの数百の要素数を想定しています。

html

1<tr> 2<td title="foo">***</td> 3<th><a href="***">bar</a></th> 4<td>***</td> 5</tr> 6 7<!--このような規則性のあるものが数百並んでいるデータを想定-->
<td>の中のtitleの属性値fooをkey、<a>で囲まれた文字barをvalueとして扱いたいです。 ```python #どこまで考えたか1

info = 'data.txt' #上記htmlの一部をtxtファイルとして保存している想定。

def molding(info):
dict = {}

with open(info) as f:
text = f.read() #文字列として取得

import re
for i in text:
foo = re.match() #titleの属性値をfoo
bar = re.match() #></a>で囲まれた部分をbarとする
dict['foo'] = 'bar' #追加

f.close()

return dict

#主題2 成分表示 `りんご、みかん, にんじん ,すいか,,レモン ,なす` この文字列をリスト型に変換したいです。 ```python #どこまで考えたか2 txt='りんご、みかん, にんじん ,すいか,,レモン ,なす' def transform(txt): l=[] txt.replace(' ' , '').replace(' ' , '').replace('、' , ',').replace(',,' , ',') # txt='りんご,みかん,にんじん,すいか,レモン,なす' import re for m in txt: m = re.match('[\u3041-\u3096 | \u30A1-\u30FF]'+, txt) #先頭から一語をmとする # IndentationError: ecpected an indented block l.append(m) #リストに入れる txt.replace(m , '').replace(',' , '') #txtの先頭から一語とカンマ1つを消す print (l) # ["''", "''", "''", "''", "''", '', '', '', '', '', '']

##つまり、わからないこと

  1. 主題1をどう書き直せばいいか
  2. 主題2をどう書き直せばいいか
  3. 正規表現でどのようにひらがなカタカナ漢字Alphabet数字を指定すればいいのか

###関連ありそうだな~と調べたことメモ

  • Beautiful Soup 4でもsoup.find_all('a')すればbarの部分は抽出できるらしいので、pythonでできないということはないはず。
  • html.parserを使用?
  • pandasやテキストマイニングはたぶん関係ない。でもたぶんオフラインデータを扱える?
  • 記号&空白で分割してgoogleスプレッドシートに落とし込んでから、そこで成型してpythonのデータ型に変換する。→たぶん同じところで躓く&より知識不足
  • EXCELのマクロでもCSVなどの整ったデータのみ?
  • pythonの辞書をhtmlにするという逆のことはできるらしい。Flaskを使用
  • 行ごとに分割してリストにするならreadlines()

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

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

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

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

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

guest

回答2

0

ベストアンサー

主題2

ひらがなのパターンの表記と、findallを組み合わせるとリストの取得ができます。

python

1>>> import re 2>>> txt='りんご、みかん, にんじん ,すいか,,レモン ,なす' 3>>> res = re.findall(r'[\u3041-\u309F]+', txt) 4>>> res 5['りんご', 'みかん', 'にんじん', 'すいか', 'なす']

主題1

BeautifulSoup4で、ローカルのHTMLも対応可能です。
記述例のHTMLであれば下記で出力できます。

python

1from bs4 import BeautifulSoup 2 3 4def molding(td_elms, a_elms, td_length: int) -> dict: 5 # td_lengthにはtrタグ内のtdタグの数を入力する 6 ret_dict = {} 7 for td_elm, a_elm in zip(td_elms[::td_length], a_elms): 8 key = td_elm["title"] # タグからtitleを取り出す 9 ret_dict[key] = a_elm.text # タグ内のテキストを取得する 10 return ret_dict 11 12 13def main(): 14 bs = BeautifulSoup(open("html.txt", encoding="utf-8"), "html.parser") 15 td_elms = bs.find_all("td") # tdタグをすべて取得する 16 a_elms = bs.find_all("a") # aタグをすべて取得する 17 ret = molding(td_elms, a_elms, 2) 18 print(ret) # {'foo': 'bar', 'fooo': 'baar', 'foooo': 'baaar'} 19 20 21if __name__ == "__main__": 22 main() 23

SampleのHTMLは以下の通りです。

html

1<html> 2<!-- 中略 --> 3 <tr> 4 <td title="foo">***</td> 5 <th><a href="***">bar</a></th> 6 <td>***</td> 7 </tr> 8 <tr> 9 <td title="fooo">***</td> 10 <th><a href="***">baar</a></th> 11 <td>***</td> 12 </tr> 13 <tr> 14 <td title="foooo">***</td> 15 <th><a href="***">baaar</a></th> 16 <td>***</td> 17 </tr> 18<-- 以下、略 -->

誤記かもしれませんが、table/tr/th/tdのReferenceを参考程度にシェアします。

追記

ひらがなとカタカナで正規表現を書いて、レモンも取得できるようにするには下の通りに書きます。

python

1>>> import re 2>>> txt='りんご、みかん, にんじん ,すいか,,レモン ,なす' 3>>> res = re.findall(r'[\u3041-\u309F\u30A1-\u30FF]+', txt) 4>>> print(res) 5['りんご', 'みかん', 'にんじん', 'すいか', 'レモン', 'なす']

投稿2020/12/13 00:57

編集2020/12/13 10:43
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

t.z

2020/12/13 09:55

ご回答ありがとうございます!BeautifulSoup4便利ですね。 3つ質問です。 ①主題2の「レモン」を残したいのですが、その場合はどう書けばよいでしょうか? 調べてもいい情報が見つかりませんでした。 ② -> この記号はなんという名前なのですか? ③def molding()のカッコの中の : int はどういう意味ですか?
退会済みユーザー

退会済みユーザー

2020/12/13 10:52 編集

① 回答に追加しました。 ② 記号の名前はわからないですが、型ヒントやアノテーションと調べるとヒントがあるかもです[ref]。 ③ td_length: intはtd_length引数にint型の値が入ることを明示しています。 [ref]: https://qiita.com/icoxfog417/items/c17eb042f4735b7924a3
t.z

2020/12/13 12:08

よくわかりました。ありがとうございます。
guest

0

主題2

python

1txt='りんご、みかん, にんじん ,すいか,,レモン ,なす' 2print(txt.translate(str.maketrans(',、', ' ')).split())

投稿2020/12/12 19:08

YouheiSakurai

総合スコア6142

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

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

t.z

2020/12/13 09:54

簡潔すぎて魔法みたいです。 便利な回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問