Path.globでファイル名に[]を含む場合のエスケープ。

 Pythonのpathlib.Pathにあるglob()ですが、どうしても引っ掛けられないファイル名が出てきて、どうすればよいか調べ中です。

具体的には、globの引数に "*[123].txt" というような、[] で囲まれた文字があるファイル名を指定したいのですが、それが引っかかってこない。どうやらワイルドカードの特殊文字になっているようです。

別のライブラリ glob には glob.escape() というメソッドがあるのですが、それを使うと今度は "*" がエスケープされてしまい、やっぱりファイルが引っかかりません。

はてさてどうしたものか……。

足りない頭で考えましたが、結局pathlib.Path.glob()で扱うことは諦めて、glob.glob()とglob.escape()を組み合わせて使うことにしました。

from glob import glob, escape
from pathlib import Path

def bracketglob(s: str):
    """generate a list of filenames from a string that contains "[]".

    []で囲まれた文字列を含むワイルドカードを展開する。

    Args:
        s(str): ファイル名文字列

    Returns:
        f(Path): glob展開されたファイル名

    """
    #
    # [] で囲まれた文字とそれ以外を別扱いにするひつようがありそう
    #
    lsqbpos = rsqbpos = -1
    l1 = l2 = l3 = ""
    if (lsqbpos := s.find("[")) != -1:
        l1 = s[0:lsqbpos]
    if (rsqbpos := s.rfind("]")) != -1:
        l3 = s[rsqbpos + 1 :]
    l2 = s[lsqbpos : rsqbpos + 1]
    if (rsqbpos - lsqbpos > 0) and (lsqbpos > 0):
        for f in glob(l1 + escape(l2) + l3):
            yield Path(f)
    else:
        for f in glob(s):
            yield Path(f)
なんとなく yield 使ってますが、そもそも for ループで glob() 使ってるからいらないんじゃね?的なギモンはあるし、力技でエレガントではない感じがジンジョーじゃない……。
処理としては、"[]" で囲まれた文字列とそれ以外を分離して3つに分けて、"[]" 文字列をescape します。"[]"は最大長で解釈させているので、

"吾輩ハ猫デアル [夏目漱石][上][大倉書店][1905].doc"

などという場合、"[夏目漱石][上][大倉書店][1905]" はすべてエスケープされるので、たぶんこの中の文字も検索対象になる…と思います。検索したいパターンに "*[大倉*]*" などとするときっと無理ですが。

0 件のコメント:

コメントを投稿

Vimの補完プラグインをインストール。その4

Vimの補完プラグインをインストール。その3 で、 ddc-tabnine が使えそうです、などと書いたのですが、早速やってみました。 まず、tabnineのバイナリを用意しないといけません。がどうにもTabNineのサイトがわかりにくいので、 tabnine-nvim にあるダ...