Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonのfnmatchモジュールで実現するUNIXスタイルのファイル名パターンマッチング

本記事では、Pythonを使ってUNIXシェル風のパターンマッチングを行う方法を解説します。この用途には、標準ライブラリのfnmatchモジュールが便利です。fnmatchモジュールは、ファイル名とパターンを比較し、一致するかどうかに応じてTrueまたはFalseを返します。

使用するには、まず標準ライブラリのfnmatchモジュールをインポートします。

import fnmatch

UNIXシェルで使えるワイルドカード

UNIXのターミナルでは、パターンマッチングに以下のようなワイルドカードを使用できます。

  • '*'(アスタリスク):すべての文字列に一致します。
  • '?'(クエスチョンマーク):任意の1文字に一致します。
  • [seq]:seq内に含まれるいずれかの文字に一致します。
  • [!seq]:seq内に含まれない文字に一致します。

アスタリスクやクエスチョンマークそのものを文字として検索したい場合は、[*][?]のように角括弧で囲んで指定します。

fnmatch()メソッド

fnmatch()メソッドは、ファイル名とパターンの2つの引数を受け取ります。この関数は、指定したファイル名がパターンに一致するかどうかを判定するために使われます。オペレーティングシステムが大文字・小文字を区別しない場合、比較の前に引数は大文字または小文字に正規化されます。

サンプルコード

import fnmatch
import os
file_pattern = 'test_f*'
files = os.listdir('./unix_files')
for filename in files:
    print('File: {}\t: {}'.format(filename, fnmatch.fnmatch(filename, file_pattern)))

実行結果

$ python3 310.UNIX_filename.py
File: test_file5.txt : True
File: test_file2.png : True
File: test_file1.txt : True
File: another_file.txt : False
File: TEST_FILE4.txt : False
File: abc.txt : False
File: test_file3.txt : True
$

この例では、「test_f」で始まるファイル名がTrueとなり、それ以外のファイルはFalseになっていることが確認できます。

filter()メソッド

filter()メソッドも2つの引数を受け取ります。第1引数はファイル名のリスト、第2引数はパターンです。このメソッドは、すべてのファイル名の中からパターンに一致するファイル名だけを抽出したリストを返します。個別に判定するよりも効率的に絞り込みができるため、複数のファイルを扱う際に便利です。

サンプルコード

import fnmatch
import os
file_pattern = 'test_f*'
files = os.listdir('./unix_files')
match_file = fnmatch.filter(files, file_pattern)
print('All files:' + str(files))
print('\nMatched files:' + str(match_file))

実行結果

$ python3 310.UNIX_filename.py
All files:['test_file5.txt', 'test_file2.png', 'test_file1.txt', 'another_file.txt', 'TEST_FILE4.txt', 'abc.txt', 'test_file3.txt']
Matched files:['test_file5.txt', 'test_file2.png', 'test_file1.txt', 'test_file3.txt']
$

translate()メソッド

translate()メソッドは、パターンという1つの引数を受け取ります。この関数を使うと、シェルスタイルのパターンをPythonの正規表現に変換できます。変換後の正規表現はreモジュールと組み合わせて利用でき、より高度なマッチング処理に応用できます。

サンプルコード

import fnmatch, re
file_pattern = 'test_f*.txt'
unix_regex = fnmatch.translate(file_pattern)
regex_object = re.compile(unix_regex)
print('Regular Expression:' + str(unix_regex))
print('Match Object:' + str(regex_object.match('test_file_abcd123.txt')))

実行結果

$ python3 310.UNIX_filename.py
Regular Expression:(?s:test_f.*\.txt)\Z
Match Object:<_sre.SRE_Match object; span=(0, 21), match='test_file_abcd123.txt'>
$

まとめ

fnmatchモジュールを活用すれば、UNIXシェルでおなじみのワイルドカード記法をそのままPythonのコードで使えます。単一ファイルの判定にはfnmatch()、一括フィルタリングにはfilter()、正規表現への変換にはtranslate()と、目的に応じてメソッドを使い分けることで、ファイル操作の柔軟性が大きく向上します。

  1. Pythonでパターンを出力する方法|三角形・数字・アルファベット・ピラミッドのコード例

    Pythonでパターンを出力するには、ネストされた(入れ子構造の)forループを使用します。外側のループで行数を制御し、内側のループで列数を処理します。そしてprint文を工夫することで、目的に応じたさまざまなパターンを作成できます。パターンには、星(アスタリスク)パターン、数字パターン、アルファベットパターンなどがあり、三角形やピラミッドなど、さまざまな形状にも対応できます。パターン出力の基本これらのパターンは、print文を少し変更しながらforループを組み合わせることで出力できます。基本的な考え方はどのパターンも共通しており、違いはごくわずかです。ここからは、代表的なパターンのコードを実

  2. Pythonで描く葉序(ようじょ)パターン ― フィボナッチ螺旋の美しさをコードで再現

    葉序パターンとは? 植物学の授業や植物の世界でよく耳にする「葉序(ようじょ)」とは、植物の茎に花・葉・種子などがどのような順序で配置されるかを表す用語です。この配置は、いわゆる「フィボナッチ螺旋」と非常によく似たパターンを示します。 フィボナッチ螺旋は、パスカルの三角形にも似た規則性を持つ数列、すなわちフィボナッチ数列に基づいています。フィボナッチ数列は次のように続きます。 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144 … この数列の特徴は、各項が直前の2つの数の和になっているという点です。自然界のあらゆる場所に潜む、シンプルながら奥深い数理構造と言えま