重命名西里尔字母文件名

4
我想要做的是遍历一个文件夹,检查文件名中是否包含任何西里尔字母,如果有,将这些文件重命名为其他名称。
我该如何做呢?

哪个版本的Python?2.x和3k在字符串处理方面非常不同。 - Justin R.
你可能会发现Unidecode很有用。 - Mark Ransom
transliterate可能也会很有用。 - unutbu
你可以像@markransom建议的那样使用ord()来缩短代码并提高速度。请参见更新的答案 - embert
3个回答

3

Python 2:

# -*- coding: utf-8 -*-
def check_value(value):
    try:
        value.decode('ascii')
    except UnicodeDecodeError:
        return False
    else:
        return True

Python 3:

在Python 3中,'str'对象没有'decode'属性。因此,您可以按照以下方式使用'encode'。

# -*- coding: utf-8 -*-
def check_value(value):
    try:
        value.encode('ascii')
    except UnicodeEncodeError:
        return False
    else:
        return True

然后您可以收集文件名,并将它们通过 check_value 函数。

我很难辨别Python 2和Python 3之间的区别 - 做出了改变以帮助解决问题。 - Thomas
1
我已更新为“为什么”有所不同。谢谢。 - CodeLikeBeaker
这不会对那些既非西里尔字母又非ASCII字符(例如希腊语)的字符返回False吗? - Justin R.
@JustinR。是的,使用Unicode块进行了回答。至少我的代码能检测出非标准ASCII字符。感谢你指出这一点。 - CodeLikeBeaker

3

Python 3
这个函数会检查传入的字符串中的每个字符,如果有斯拉夫文字,则返回True。在Python3中,默认情况下字符串是unicode编码的。该函数将每个字符编码为utf-8,并检查是否生成两个字节与包含斯拉夫文字的表块相匹配。

def isCyrillic(filename):
    for char in filename:            
        char_utf8 = char.encode('utf-8')      # encode to utf-8 

        if len(char_utf8) == 2 \              # check if we have 2 bytes and if the
            and 0xd0 <= char_utf8[0] <= 0xd3\ # first and second byte point to
            and 0x80 <= char_utf8[1] <= 0xbf: # Cyrillic block (unicode U+0400-U+04FF)
            return True

    return False

使用评论中建议的ord()函数实现相同功能

def isCyrillicOrd(filename):
    for char in filename:                  
        if 0x0400 <= ord(char) <= 0x04FF:    # directly checking unicode code point
            return True

    return False

测试目录

cycont
   |---- asciifile.txt
   |---- кириллфайл.txt
   |---- украї́нська.txt
   |---- संस्कृत.txt

测试

import os
for (dirpath, dirnames, filenames) in os.walk('G:/cycont'):
    for filename in filenames:
        print(filename, isCyrillic(filename), isCyrillicOrd(filename))

输出

asciifile.txt False False
кириллфайл.txt True True
украї́нська.txt True True
संस्कृत.txt False False

为什么要费力地转换为UTF-8,当你可以直接测试字符的ord()呢? - Mark Ransom
很容易回答:我不知道 ord()。做了适当的更新。 - embert

1

有一个与此相关的库:Python的transliterate lib

首先,您需要获取文件名。为此,请使用os.listdir():

from os import listdir
from os.path import isfile, join
files = [ f for f in listdir(dir) if isfile(join(dir,f)) ]

现在,您可以查看files中的每个文件,并根据需要替换任何字符:
import transliterate
newName = translit(filename, 'ru', reversed=True)

然后只需使用 os.rename 重命名文件:

os.rename(filename, newName)

listdir() 的问题在于,它返回的文件名应该是用西里尔字母书写的,但实际上却返回了问号。 - Mario Geuenich
@MarioGeuenich:问号是由于文件名中字节的编码与终端的编码不匹配造成的。这不是listdir的错。还要注意,如果您传递给listdir一个Unicode,则它将返回Unicode文件名。但是,仍然需要您使用终端期望的编码对Unicode进行编码,并确保该Unicode可以使用该编解码器进行编码。这可能是Windows上的问题 - unutbu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接