質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

正規表現

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

Q&A

1回答

915閲覧

正規表現を使用してリストから検索をかける

KohnoseLami

総合スコア17

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

正規表現

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

0グッド

1クリップ

投稿2021/06/02 11:39

前提・実現したいこと

正規表現を使用して大規模なリストの中から検索をかけて一致したもの全てを出力させたいです。
この際database.txtには7000万ほどデータが含まれています。これを軽量化し高速化させる方法はありますか?

該当のソースコード

Python3

1from tqdm import tqdm 2import re 3 4with open("list.txt", "r", encoding="utf-8") as f: 5 re_list = [re.compile(i.split(" - ")[1].split(":")[-1].replace('*', '[0-9a-zA-z\-]').replace('.', '.') + ":") for i in f.read().strip().split("\n")] 6print(re_list) 7 8with open("database.txt", "r", encoding="utf-8") as f: 9 l_re_match = [] 10 database = f.read().strip().split("\n") 11 for _ in tqdm(re_list): 12 l_re_match.extend(list(set([i for i in database if _.match(i)]))) 13 14with open("output.txt", "w", encoding="utf-8") as f: 15 f.write("\n".join(l_re_match)) 16 17for i in l_re_match: 18 print(i) 19

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

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

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

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

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

takasima20

2021/06/02 11:45

データベース使ったら?
KojiDoi

2021/06/02 12:15

list.txt database.txtはそれぞれどういう内容なのでしょうか? 正規表現でスライスしようとしているようですが、それにしてはreplaceを2回も挟んだりして、ここに無駄に時間を掛けてるような気がします。
KohnoseLami

2021/06/03 02:28

先にlist.txtに格納されている伏せ字で構成された文字列を正規表現に変換しています。 Koh******** ⇣ Koh[0-9a-zA-z\-][0-9a-zA-z\-][0-9a-zA-z\-][0-9a-zA-z\-][0-9a-zA-z\-][0-9a-zA-z\-][0-9a-zA-z\-][0-9a-zA-z\-] ⇣ KohnoseLami といったふうに一度伏せ字を正規表現に変換してそれを使用してdatabaseから抽出しています。 これを高速でやる方法が見当たらず質問させていただきました
KojiDoi

2021/06/03 03:03

これがpythonの学習目的ではなく、実務上の要請なのだとすると、grepとかsedとか使ったほうがずっと高速じゃないですかね。
KohnoseLami

2021/06/03 03:56

なるほど... そうですね、私がかけるのがPython、PHPくらいなのでPythonでやろうと考えていましたがやはりそういった言語やMySQLでデータベースを構築してしまったほうが早いですかね...
KojiDoi

2021/06/03 05:52

データベース化するにしてもSQLで処理できるような形にまずは加工しないわけにはいかないでしょう。抽出作業を高速化したいということですから、これは前処理の問題です。
KojiDoi

2021/06/03 06:22

ところで、OSは何でしょうか。
guest

回答1

0

  • 一気に読まない。read()はファイル全量を一度にメモリへロードします。行単位で正規表現を適用するなら、readline()で1行ずつ読み込んで処理しないととんでもなく遅くなると思われます。
  • マッチした行を配列に貯めない。どのくらいマッチするかは謎ですが相当量のマッチ行がl_re_matchに溜まればそれもメモリを大きく消費します。単純にoutput.txtに行を書き出すのであればマッチしたらすぐにwriteしてしまった方が良いでしょう。
  • もし「明らかに正規表現にマッチしない」と事前にわかる行の判別ができるのであれば、正規表現を適用せずにスキップすることで処理時間を減らせるでしょう。

とにかく、消費メモリを削減しないと動作が速くなりません。メモリ不足でスワップが発生するのが最もボトルネックになります。

投稿2021/06/02 16:48

hope_mucci

総合スコア4447

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

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

KohnoseLami

2021/06/03 02:23

回答ありがとうございます! readlineをすっかり忘れていました。 全て正規表現でのチェックが必要のためreadlineで試してみたいと思います。 大体テキストの総量などは、データベースが7000万行、正規表現を一致させるためのテキストが20000行、20000行のテキストを全て正規表現に置き換えてそれに一致するものを出力させたいです。 大体1個の正規表現で0~3000個出力されます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問