記事内にはプロモーションが含まれています

Pythonでワイルドカードを使う方法!globや正規表現での検索を徹底解説

Pythonでワイルドカードを使う方法!globや正規表現での検索を徹底解説 プログラミングの疑問解決

Pythonでファイル操作や文字列処理を行っていると、「特定のパターンに一致するファイルだけを抜き出したい」「文字列の一部があいまいでも検索したい」という場面によく遭遇します。

そんな時に役立つのが「ワイルドカード」です。

ワイルドカードを使いこなせば、数百個あるファイルの中から「.jpg画像だけ」を一瞬でリストアップしたり、複雑な文字列の中から「数字で始まるデータ」だけを抽出したりといった処理が、わずか数行のコードで実現できます。

この記事では、Pythonにおけるワイルドカードの基礎から、ファイル検索で使うglobモジュール、文字列検索で使うre(正規表現)モジュールの使い方まで徹底解説します。

【著者プロフィール&本記事の信頼性】
プロフィール
  • 著者は元エンジニア
  • 大手プログラミングスクールのWebディレクター兼 ライターを経験
  • 自らも地元密着型のプログラミングスクールを運営
プロフィール詳細はコチラ
日本最大級の比較サイトで「4年連続人気NO.1」!
SNSでの評判の良さも圧倒的なプログラミングスクール『RUNTEQ(ランテック)』!
【RUNTEQの特徴】
✅受講生からの評判が驚くほど良い
✅学習はハードだが未経験とは思えないほど高いスキルが身に付く
挫折させない万全なサポート体制が用意されている
✅採用面接で担当者に刺さるレベルの高い「ポートフォリオ」を作成できる
✅給付金を使えば実質約13万円という格安料金で受講できる
当ブログ著者
当ブログ著者
忖度一切なしで、未経験から本気で
エンジニア転職を目指すならRUNTEQ一択です。

\勧誘行為は一切なし! 相談だけでもOK! /

ワイルドカードとは?基本の記号と意味

ワイルドカードとは、検索などを行う際に「任意の文字」や「任意の文字列」を代用して表現するための特殊な記号のことです。
トランプの「ジョーカー(万能札)」のようなものだとイメージするとわかりやすいでしょう。

Python(および多くのコンピュータシステム)で主に使用されるワイルドカード記号は以下の2つです。

  • *(アスタリスク): 「0文字以上の任意の文字列」を表します。
  • ?(クエスチョンマーク): 「任意の1文字」を表します。

* と ? の違いを具体例で確認

例えば、「test」で始まり、拡張子が「.txt」であるファイルを探したい場合の違いを見てみましょう。

パターン 意味 ヒットする例 ヒットしない例
test*.txt testの後に何文字あっても(なくても)よい test.txt

 

test1.txt

 

test_data.txt

tes.txt(testがない)
test?.txt testの後に必ず1文字ある test1.txt

 

testA.txt

test.txt(0文字はNG)

 

test12.txt(2文字はNG)

このように、状況に応じて使い分けることで、より正確な検索が可能になります。

ファイル検索でのワイルドカード活用【glob / pathlib】

Pythonでワイルドカードを最も頻繁に使うシーンは、「フォルダ内のファイル検索」でしょう。

ここでは、伝統的なglobモジュールと、近年主流となっているpathlibモジュールを使った方法を紹介します。

基本:globモジュールでファイルリストを取得する

globモジュールは、Unixシェル形式のワイルドカードパターンを使ってファイルパスのリストを取得するための標準ライブラリです。

使い方は非常にシンプルです。
glob.glob()関数の引数に、ワイルドカードを含んだパス文字列を渡すだけです。

import glob

# カレントディレクトリにある全ての .txt ファイルを取得
# * は「任意のファイル名」を表す
txt_files = glob.glob('*.txt')

print(txt_files)
# 出力例: ['memo.txt', 'report.txt', 'sample.txt']

# 'data_' で始まるファイルのみ取得
data_files = glob.glob('data_*')
print(data_files)
# 出力例: ['data_01.csv', 'data_backup.log']

応用:再帰的な検索(サブフォルダも検索)

「フォルダの中にあるサブフォルダまで全部探したい」という場合は、**(ダブルアスタリスク)というワイルドカードを使用し、引数recursive=Trueを指定します。

import glob

# 現在のフォルダ以下、すべての階層にある .jpg 画像を探す
# ** は「任意の階層(ディレクトリ)」を表す
images = glob.glob('**/*.jpg', recursive=True)

for img in images:
    print(img)

# 出力例:
# images/photo1.jpg
# images/vacation/beach.jpg
# backup/old/icon.jpg

モダンな記述:pathlibモジュールでのワイルドカード

Python 3.4以降で導入されたpathlibモジュールは、ファイルパスを「文字列」ではなく「オブジェクト」として扱えるため、より直感的で便利な操作が可能です。

現在、新規開発ではglobよりもpathlibの使用が推奨される傾向にあります。

pathlibでもglob()メソッドを使ってワイルドカード検索が可能です。

from pathlib import Path

# カレントディレクトリを表すPathオブジェクトを作成
p = Path('.')

# pathlibでは glob() メソッドを使う
# 戻り値は文字列のリストではなく、Pathオブジェクトのジェネレータになる
for file_path in p.glob('*.py'):
    print(file_path.name)

# 再帰的な検索は rglob() メソッドを使うと便利(recursive globの略)
# **/*.txt と同じ意味になる
for txt_path in p.rglob('*.txt'):
    print(txt_path)

【応用】globで使えるその他のワイルドカード記号

*? 以外にも、globでは「範囲指定」を行うためのワイルドカードが使用できます。
これを知っておくと、より細かい条件でのファイル抽出が可能になります。

[]:指定した文字のいずれかにマッチ

角括弧 [] を使うと、その中に記述した文字のいずれか1文字にマッチします。

  • file[123].txt
    • マッチする:file1.txt, file2.txt, file3.txt
    • マッチしない:file4.txt, file12.txt

[ - ]:文字の範囲を指定

ハイフン - を使うと、文字や数字の範囲を指定できます。

  • data[0-9].csv (0から9までの数字1文字)
    • マッチする:data0.csv, data5.csv, data9.csv
  • image[a-z].jpg (aからzまでの英小文字1文字)
    • マッチする:imagea.jpg, imagez.jpg

[! ]:指定した文字「以外」にマッチ(否定)

感嘆符 ! を先頭につけると、その文字以外にマッチします。

  • file[!0-9].txt (数字以外の文字が含まれるファイル)
    • マッチする:fileA.txt, file_.txt
    • マッチしない:file1.txt

文字列マッチングでのワイルドカード活用【正規表現】

ファイル名ではなく、「テキストデータの中身」や「変数に入っている文字列」に対してワイルドカードのような曖昧検索を行いたい場合は、正規表現を使用します。

Pythonでは標準ライブラリのreモジュールを使います。

正規表現におけるワイルドカード「.」

ファイル検索(シェル形式)のワイルドカードとは記号が異なるため注意が必要です。

正規表現では、ドット(.)が「任意の1文字」を表すワイルドカードとして機能します。

そして、「直前の文字の0回以上の繰り返し」を表すアスタリスク(*)と組み合わせた、.* というパターンが、「任意の文字列(0文字以上)」という意味になります。

シェル形式 (glob) 正規表現 (re) 意味
? . 任意の1文字
* .* 任意の文字列

reモジュールを使った部分一致検索の実装

re.search()re.findall()を使って、文字列の中からパターンに一致する部分を探し出します。

import re

text = "私のIDは user-1234 です。彼のIDは user-9876 です。"

# ワイルドカードを使ったパターン定義
# user- の後に、任意の文字(.)が繰り返される(*)
# しかし .* だと行末までマッチしてしまうため、ここでは数字だけ \d+ を使うか
# 最小マッチ .*? を使うのが一般的

# 例: user- で始まり、スペースが来るまでの任意の文字列を抽出
# user-.*? というパターンを使う
pattern = r"user-.*?"

# マッチするものをすべてリストで取得
# 注意: 上記の単純な .*? だけでは区切りが判断できないため、
# ここでは分かりやすく「数字の連続」をワイルドカード的に抽出する例とします
# \d は数字1文字を表す特殊文字(ワイルドカードの一種)
pattern_id = r"user-\d*" 

matches = re.findall(pattern_id, text)

print(matches)
# 出力例: ['user-1234', 'user-9876']

文字列の一部置換(re.sub)

ワイルドカード(正規表現)を使って、特定パターンに一致する部分を別の文字列に置き換えるには、re.sub()を使います。

これはreplace()メソッドの強化版と言えます。

import re

text = "ファイル名: document_v1.txt, document_final.txt"

# document_〇〇.txt の部分を [REMOVED] に置き換える
# .*? は「任意の文字列(最短一致)」
pattern = r"document_.*?\.txt"

new_text = re.sub(pattern, "[REMOVED]", text)

print(new_text)
# 出力例: ファイル名: [REMOVED], [REMOVED]

簡易的な部分一致(in演算子 / startswith)

「ワイルドカードや正規表現を使うほどではないけれど、単純に特定の文字が含まれているか知りたい」という場合は、Pythonの標準的な文字列メソッドを使うのが最も高速で読みやすい方法です。

  • in 演算子: 文字列が含まれているか(部分一致)
  • startswith(): 指定の文字で始まっているか(前方一致)
  • endswith(): 指定の文字で終わっているか(後方一致)
filename = "report_2025.pdf"

# 1. 部分一致(ワイルドカード *2025* に相当)
if "2025" in filename:
    print("2025年のファイルです")

# 2. 前方一致(ワイルドカード report* に相当)
if filename.startswith("report"):
    print("レポートファイルです")

# 3. 後方一致(ワイルドカード *.pdf に相当)
if filename.endswith(".pdf"):
    print("PDFファイルです")

ワイルドカードが上手く動かない?よくあるトラブルと対処法

Pythonでワイルドカードを使用していると、「あるはずのファイルがヒットしない」といった問題に直面することがあります。

ここでは代表的なトラブルシューティングを紹介します。

隠しファイル(ドットファイル)がヒットしない

LinuxやmacOSでは、.(ドット)で始まるファイルは「隠しファイル」として扱われます。

glob.glob('*') と記述しても、デフォルトではこれらの隠しファイル(例:.gitignore, .env)は検索結果に含まれません。

対処法: Python 3.10以降では、glob関数に include_hidden=True オプションを渡すことで取得可能です。

# 隠しファイルも含めて取得する(Python 3.10+)
files = glob.glob('*', include_hidden=True)

ファイル名に「[」や「*」が含まれている場合

ファイル名自体に data[1].txt のようにワイルドカード記号が含まれていると、globはそれを「パターンの指定」と誤認してしまい、正しくファイルを見つけられません。

対処法: glob.escape() を使って、パスに含まれる特殊文字をエスケープ(無効化)します。

import glob

filename = 'data[1].txt'
# 特殊文字をエスケープしてから検索
safe_pattern = glob.escape(filename) 
print(glob.glob(safe_pattern))

Pythonのワイルドカードに関するよくある質問

ここでは、Pythonでワイルドカードを使用する際によくある質問についてまとめましたので、参考にしてください。

Q. globとos.listdir、どちらを使うべき?

フィルタリングが必要ならglob、全ファイル操作ならos.listdir(またはscandir)がおすすめです。

すべてのファイルを取得してからPython側でif文で選別するよりも、globで最初に絞り込んだ方がコードが簡潔になります。

ただし、数万ファイルを超えるような大量データの処理速度を最優先する場合は、os.scandir の方が高速な場合があります。

正規表現のワイルドカード「.」と「*」の違いは?

「.」は文字の種類、「*」は文字の数を表します。

  • . : 「あ」「a」「1」など、なんでもいい1文字
  • * : 直前の文字が0回以上繰り返されること。 これらを組み合わせた .* で初めて「任意の文字列」という意味になります。

初心者がPythonのワイルドカードについて効率的に学ぶには

Pythonのワイルドカードの使い方をはじめとするPythonのスキルを効率的に習得するには、プログラミングスクールの活用が最も近道です。

スクールでスキルを高めることにより、今の仕事に活かしたり、副業として高単価な案件を受注できたりするだけでなく、Pythonエンジニアとして転職することも可能になります。

Pythonエンジニアは需要が非常に高いため、それに比例して年収も高くなる傾向にあります。
「今よりも年収を上げたい」「将来性の高い職種であるエンジニアへ転職したい」といった気持ちが強い場合は、プログラミングスクールでPythonの専門スキルを習得しつつ、ポートフォリオ支援や転職支援を受けてエンジニアへ転職する、という道を目指すのもよいでしょう。

なお、「Pythonに強く、受講生からの評判も良いプログラミングスクール」には、以下のようなところがあります。

その他、以下の記事でもPythonのおすすめスクールをまとめていますので、興味のある方は是非参考にしてください。