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

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

新規登録して質問してみよう
ただいま回答率
85.47%
エスケープ処理

エスケープ処理とは、一連の文字や一文字に対して、一定の規則に従って別の意味を適用する処理過程です。

正規表現

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

Python

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

Q&A

解決済

1回答

1184閲覧

正規表現での"()"のエスケープの仕方が分かりません。

rapsody

総合スコア7

エスケープ処理

エスケープ処理とは、一連の文字や一文字に対して、一定の規則に従って別の意味を適用する処理過程です。

正規表現

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

Python

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

0グッド

0クリップ

投稿2019/10/19 16:07

前提・実現したいこと

(3).csv や (10).csvなどのcsvファイルを正規表現で指定して取り出したいです。

発生している問題・エラーメッセージ

上手く取り出せずリストが空になります。

該当のソースコード

Python 3.7.3

print([p for p in glob.glob('./temp/*.csv', recursive=True)
if re.search('(\d+).csv', p)])

試したこと

"()"をエスケープしたり、ネットでググりましたがよくわかりません。どうぞよろしくお願いします。

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

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

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

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

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

KojiDoi

2019/10/19 18:07

その「ソースコード」は明らかに文法的に不完全ですね。 正規表現以前の段階でうまくいくはずがないので、まずはそこを見直してください。
dodox86

2019/10/19 18:51

> 文法的に不完全ですね。 私も一瞬、p for p の時点で「あれ?」と思ったのですが、大丈夫なようです。 C>type t1.py import glob import re print([p for p in glob.glob('./temp/*.csv', recursive=True) if re.search('\(\d+\).csv', p)]) C>python -m py_compile t1.py コンパイル、文法チェックにも引っ掛かりませんでした。
KojiDoi

2019/10/19 19:28

>大丈夫なようです。 そのようですね…私の試したpythonのバージョンが古かったのが敗因のようです。 質問者様失礼しました。
guest

回答1

0

ベストアンサー

CSVファイルの拡張子 *.csvが、全て小文字である限り、質問者さんの元のコードで動作しました。もしかするとWindows環境下で動作させていますでしょうか。Windowsですと、ファイル名は英大文字小文字を区別しませんので、そのせいかもしれません。

例えば、./temp下に以下のように拡張子CSVについて、大文字小文字が混在しているものがあるとします。

CMD

1C>dir /b temp 2(1).csv 3(11).csv 4(12).CSV 5(123).CsV 6(2).CSV 7(3).CsV

これを、質問者さんのもとのコードで試すと以下のような結果となります。

CMD

1C>python --version 2Python 3.7.4 3 4C>type t1.py 5import glob 6import re 7 8print([p for p in glob.glob('./temp/*.csv', recursive 9if re.search('(\d+).csv', p)]) 10 11C>python t1.py 12['./temp\(1).csv', './temp\(11).csv']

拡張子として全てが小文字の *.csv のみがマッチします。ですので、この場合は大文字小文字を区別しないようにすると良いです。

python3

1import glob 2import re 3 4print([p for p in glob.glob('./temp/*.[cC][sS][vV]', recursive=True) 5if re.search('(\d+).csv', p, re.IGNORECASE)]) 6

これで実行すると、以下のようになります。

CMD

1C>python t2.py 2['./temp\(1).csv', './temp\(11).csv', './temp\(12).CSV', './temp\(123).CsV', 3 './temp\(2).CSV', './temp\(3).CsV']

追記しました:2019-10-20 12:59

回答へコメントいただいた件、".\temp(1)-(4).csv"のようなファイル名を除外する場合は、ファイル名に先行するパス区切り文字('\'または'/')をパターンとすることで対応できます。※つまり、ファイル名に先行してディレクトリ名があることを前提としますので、改造するような場合は注意してください。

python3

1if re.search('[\/](\d+).csv', p, re.IGNORECASE)])

投稿2019/10/19 18:44

編集2019/10/20 03:59
dodox86

総合スコア9183

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

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

dodox86

2019/10/19 19:15

細かいことを書くと、re.search('(\d+).csv'の正規表現の部分は、'(\d+).csv' の方がより正確かと思います。拡張子のドット'.'は、そのままだと正規表現の任意の1文字して扱われてしまうので。本質問のケースに限ってはglobでのファイル名検索パターンで既にフィルタリングされているので、問題は起きませんが。
rapsody

2019/10/20 03:32

丁寧に回答いただきありがとうございます。やってみましたが、(1)-(4).csvのようなファイルも抽出してしまいます。。。 temp/(1).csv、(2).csv、 〇〇.csv、 (1)-(4).csv   の中から、(数字).csv のようなファイルだけ取り出したいです。 (\d+).csv で指定しているはずなのに、なぜ、(1)-(4)のようなファイルも取り出してしまうのでしょうか?
dodox86

2019/10/20 03:40

まず確認ですが、Windows環境ですよね? パターン"(\d+).csv" は、"(1)-(4).csv" のおしり側、"(4).csv"の部分にマッチしてるのだと思います。確認の上、追記します。
dodox86

2019/10/20 04:00

追記しましたので確認してみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問