首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python中使用glob.glob和带有unicode文件名的正则表达式的文件系统独立方式

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

Stack Overflow用户
提问于 2015-04-27 18:29:01
回答 2查看 921关注 0票数 2

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

例如(在Mac上,使用IPython,Python2.7):

代码语言:javascript
复制
   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'ü-*.é')。当我试图将文件名与正则表达式匹配时,也会出现同样的问题:只有在Mac上规范化为NFD的unicode正则表达式与文件名匹配,而只有NFC正则表达式匹配在Linux/Windows上读取的文件名(在这两种情况下我都使用re.UNICODE标志)。

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

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

然而,我既找不到这样的函数,也找不到一种安全/标准的方法来对它进行特性测试。

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

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-30 15:48:46

我假设您希望匹配unicode 等价物文件名,例如,您期望u'\xE9*'的输入模式在任何操作系统上都匹配文件名u'\xE9qui'u'e\u0301qui',即字符级模式匹配。

您必须理解,在Linux上,这不是默认的,在Linux中,字节被视为字节,并且不是每个文件名都是当前系统编码中的有效unicode字符串(尽管Python3使用了“代理转义”错误处理程序来将这些字符串表示为str )。

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

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2015-04-27 18:29:01

我就是这样解决问题的:

代码语言:javascript
复制
import unicodedata as U

    # ...

    globPattern = os.path.join(folder, prefix + u'*' + suffix)
    rawRegEx = prefix + u'([0-9]+)' + suffix + u'$'

    # Mac uses NFD normalization for Unicode filenames while windows
    # linux/windows use NFC normalization
    if sys.platform.startswith('darwin'):
        normalizedGlobPattern = U.normalize('NFD', globPattern)
        normalizedRegEx = U.normalize('NFD', rawRegEx)
    else:
        normalizedGlobPattern = U.normalize('NFC', globPattern)
        normalizedRegEx = U.normalize('NFC', rawRegEx)

    allFiles = glob.glob(normalizedGlobPattern)

    # ...

    numFilesRegEx = re.compile(normalizedRegEx, _re.UNICODE)
    numberedFiles = (re.search(numFilesRegEx, f) for f in allFiles
                     if re.search(numFilesRegEx, f))

这似乎通过了我可以在AppVeyor (Windows)、Travis (Linux)和我的笔记本电脑(Mac + HFS+)上进行的所有测试。

但是,我不确定是安全的还是,是否有更好的方法编写。例如,我不知道它是否能在装有NFS的Mac上工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29903338

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档