在 Python 中使用 glob.glob 和带有 unicode 文件名的正则表达式的独立于文件系统的方式

2024-04-27

我正在开发一个库,我想保持平台、文件系统和 Python2.x/3.x 的独立性。但是,我不知道如何以独立于平台/文件系统的方式全局查找文件并将文件名与正则表达式进行匹配。

例如。 (在 Mac 上,使用 IPython、Python 2.7):

   In[7]: from glob import glob
   In[8]: !touch 'ü-0.é' # Create the file in the current folder

   In[9]: glob(u'ü-*.é')
  Out[9]: []

   In[10]: import unicodedata as U

   In[11]: glob(U.normalize('NFD', u'ü-*.é'))
  Out[11]: [u'u\u0308-0.e\u0301']

但是,这在 Linux 或 Windows 上不起作用,我需要unicode.normalize('NFC', u'ü-*.é')。当我尝试将文件名与正则表达式匹配时,会出现同样的问题:只有 unicode 正则表达式规范化为NFD在 Mac 上匹配文件名,而只有NFC正则表达式匹配在 Linux/Windows 上读取的文件名(我使用re.UNICODE两种情况下都标记)。

有处理这个问题的标准方法吗?

我的希望是就像sys.getfilesystemencoding()返回文件系统的编码,将存在一个返回底层文件系统使用的 Unicode 规范化的函数。

然而,我既找不到这样的函数,也找不到对其进行功能测试的安全/标准方法。


Mac + HFS+使用 NFD 标准化:https://apple.stackexchange.com/a/10484 https://apple.stackexchange.com/a/10484

Linux + Windows 使用 NFC 标准化:http://qerub.se/filenames-and-unicode-normalization-forms http://qerub.se/filenames-and-unicode-normalization-forms

代码链接:https://github.com/musically-ut/seqfile/blob/feat-unicode/seqfile/seqfile.py https://github.com/musically-ut/seqfile/blob/feat-unicode/seqfile/seqfile.py


我假设你想匹配 unicode相等的 http://en.wikipedia.org/wiki/Unicode_equivalence文件名,例如您期望的输入模式为u'\xE9*'匹配两个文件名u'\xE9qui' and u'e\u0301qui'在任何操作系统上,即字符级模式匹配。

你必须明白,这不是 Linux 上的默认设置,在 Linux 中,字节被视为字节,并且并非每个文件名都是当前系统编码中的有效 unicode 字符串(尽管 Python 3 使用 'surrogateescape' 错误处理程序将它们表示为str反正)。

考虑到这一点,这是我的解决方案:

def myglob(pattern, directory=u'.'):
    pattern = unicodedata.normalize('NFC', pattern)
    results = []
    enc = sys.getfilesystemencoding()
    for name in os.listdir(directory):
        if isinstance(name, bytes):
            try:
                name = name.decode(enc)
            except UnicodeDecodeError:
                # Filenames that are not proper unicode won't match any pattern
                continue
        if fnmatch.filter([unicodedata.normalize('NFC', name)], pattern):
            results.append(name)
    return results
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Python 中使用 glob.glob 和带有 unicode 文件名的正则表达式的独立于文件系统的方式 的相关文章

随机推荐