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

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

詳細はこちら
Python 3.x

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

正規表現

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

Python

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

Q&A

2回答

2223閲覧

正規表現findallで出力した空のリスト[]の扱い方について

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

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

正規表現

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

Python

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

0グッド

0クリップ

投稿2019/11/11 08:02

編集2019/11/11 13:46

テキストファイル【test_text.txt】から【開催月】の一覧を「年」と「月」に分けて抜き出し、それぞれファイルに書き込みpandasで処理をしたいと考えています。
(該当コードでは和暦を西暦に変換する関数【seireki()】を組み込みながら書いています。)

【test_text.txt】

イベント名 〇〇祭り 開催地 東京都 開催月 平成 3 年 10 月 平成 4 年 1 月 平成 5 年 7 月 平成 8 年 10 月 備考 毎年10月の2週目の土曜日に開催 イベント名 〇〇パーティー 開催地 東京都 開催月 昭和 51 年 2 月 昭和 51 年 6 月 昭和 53 年 9 月 昭和 58 年 10 月 備考 . . .

【test_text.txt】には1000以上のイベントが同じように記入されており、抜き出したい【開催月】は必ず「開催月」の下に記されています。

myfile = open('test_text.txt', 'r', encoding='utf-8_sig') data = myfile.readlines() myfile.close() d_len = len(data) a = [] for i in range(d_len): element = data[i] element = element.rstrip() if(element=='開催月'): start_list = data[i+1].rstrip() #開催月の抜き出し start_list= start_list.replace(' ','') #空白を削除 start_seireki = re.findall(r'.+年', toshi_list) #開催月の開催年を西暦で抜き取る start_month = re.findall(r'[0-9]+月', toshi_list) #開催月の開催月を抜き取 for ss in start_seireki: ss = seireki(ss).replace('年','') #和暦を西暦に変換する関数seireki()を使用 a.append(ss) #print(a) #ここで【出力結果1】が返ってきます

【出力結果1】

['1991年'] ['1975年'] [] ['1989年'] ['1985年'] [] ['1879年'] ['1991年'] . . .

発生している問題

上記のコードを書くと【出力結果1】のように所々空のリスト[]になってしまいます。
空のリスト[]をNaNやNoneで埋めるにはどのようなコードを書けばよろしいでしょうか?

試したこと

どう調べていいかわからずつまづいてしまいました。
どなたかご教授よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

windows
google colaboratory
ここにより詳細な情報を記載してください。

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

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

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

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

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

y_waiwai

2019/11/11 08:09

なぜNaNやNoneで埋めるのでしょうか。 なにか理由はありますか?
退会済みユーザー

退会済みユーザー

2019/11/11 09:04

そのまま二次元配列にしDataFrameに結合したら、足らない要素数分詰められてしまったのでデータにズレが生じてしまいました。 そのため、先に穴埋めしたいと思いました。。
kazto

2019/11/11 09:06

空のリストが含まれる、ということは、元データが「○○年」というフォーマットに従っていない行が存在する、ということでよいでしょうか。 また、空であるかどうかは、`len(list_item) == 0` といった具合に判別できるので、Noneなどを挿入する目的をお教え願えますでしょうか。
退会済みユーザー

退会済みユーザー

2019/11/11 09:13

先に穴埋めしたい理由は上記の通りです! >空のリストが含まれる、ということは、元データが「○○年」というフォーマットに従っていない行が存在する、ということでよいでしょうか。 なるほど…その場合だったとしても、その要素は欠損地として扱いたいと考えています。
LouiS0616

2019/11/11 10:22 編集

※勘違いであったためいったん削除
guest

回答2

0

足らない要素数分詰められてしまったのでデータにズレが生じてしまいました。

findallを二回走らせる意義が薄いように感じます。
例えば次のように行ごとにマッチを行った方が辻褄が合いやすいのではないでしょうか。

Python

1import re 2import sys 3 4 5raw_days = sys.stdin.read().splitlines() 6 7days = [] 8for raw_day in raw_days: 9 l = re.fullmatch(r'((?:昭和|平成)\d{1,2}年)?(\d{1,2}月)?', raw_day) 10 days.append(l.groups()) 11 12print(*days, sep='\n')

実行結果 Wandbox

('昭和46年', '10月') ('平成2年', '12月') ('昭和39年', None) ('昭和42年', '11月') (None, '9月') ('昭和50年', '6月')

コメントを受けて

徐々にデータを削り取っていけば良いのです。

Python

1import re 2import sys 3 4 5raw_data = sys.stdin.read() 6 7# イベントごとに分けて 8events = re.split(r'\n(?=イベント名)', raw_data) 9 10event_months = [] 11for event in events: 12 # 開催月の行を取得して 13 m = re.search(r'開催月\n(.*)\n?備考', event).group(1) 14 # 無駄な空白を削除して 15 m = re.sub(r'\s', '', m) 16 17 # 正規表現で解析 18 m = re.fullmatch(r'((?:昭和|平成)\d{1,2}年)?(\d{1,2}月)?', m).groups() 19 event_months.append(m) 20 21# できあがり 22print(event_months)

実行結果 Wandbox

[('平成3年', '10月'), ('昭和51年', '2月'), (None, None)]

投稿2019/11/11 10:35

編集2019/11/11 13:22
LouiS0616

総合スコア35668

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

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

退会済みユーザー

退会済みユーザー

2019/11/11 11:59

混乱してしまったため大幅に修正させていただきました。 コードなどを全て書かせていただきました。
LouiS0616

2019/11/11 12:21

『所々空のリスト[]になってしまう』行は、どんなふうになっているのでしょうか。 年あるいは月が省略されているケースがあるのですか?それとも正規表現でのマッチに失敗するケースがあるのですか?
退会済みユーザー

退会済みユーザー

2019/11/11 12:46

空になってしまう箇所は元々のテキスト内で 平成 〇 年 〇 月 自体が記入されていないようです。。
LouiS0616

2019/11/11 12:50

> 平成 〇 年 〇 月 自体が記入されていないようです。。 『開催日』というラベル自体はあるのですか? --- また、そのイベントは完全に無視して良いのでしょうか? あるいは年も月もNoneにしますか?
退会済みユーザー

退会済みユーザー

2019/11/11 13:00

>『開催日』というラベル自体はあるのですか? あります! >また、そのイベントは完全に無視して良いのでしょうか?あるいは年も月もNoneにしますか? 空白を作りたくないので、できればすべてを穴埋めしたいです。。
LouiS0616

2019/11/11 13:22

追記しました。
退会済みユーザー

退会済みユーザー

2019/11/11 13:44

何度もご回答ありがとうございますm(__)m 申し訳ないのですが、もう一点修正させていただきます。。 ややこしくなってしまいすみません。。
LouiS0616

2019/11/11 13:48

流れは一緒です。 ・イベントごとに分ける ・開催月を示す全ての行を取得する ・その各要素について、正規表現で解析
退会済みユーザー

退会済みユーザー

2019/11/11 13:49

実はこのテキストファイルは元々PDFのデータをテキストファイルにしたもので、 「昭和(平成)〇〇年 〇〇月」という情報が4つ並んでいるんです。。
退会済みユーザー

退会済みユーザー

2019/11/11 13:50

>イベントごとに分ける というのは、(?=イベント名)にイベントを一個ずつ打ち込んでいくということでしょうか?
LouiS0616

2019/11/11 13:56 編集

その部分は開催月の項目が何行あろうと処理は変わらない筈です。
guest

0

私ならこうやる、という一例です。

Python

1seireki_with_none = [[None] if len(v) == 0 else v for v in seireki]

投稿2019/11/11 09:23

kazto

総合スコア7196

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

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

退会済みユーザー

退会済みユーザー

2019/11/11 09:52

ご回答ありがとうございます! このコードを入れても空のリスト[]のままで結果が返ってきてしまいました。。汗
kazto

2019/11/11 10:00

少なくとも私の手元では意図通りNoneが挿入されて動作しています。 pilomuさんのコードをご提示いただければ、どこで上手く行っていないか判断できます。
退会済みユーザー

退会済みユーザー

2019/11/11 12:00

修正させていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問