python工具(2) — 文件名检测

在移动游戏开发中,针对Windows与移动平台对文件名大小写敏感性的差异,本文介绍了一款使用Python正则表达式编写的工具。该工具检查Lua代码中引用的资源文件名,确保它们在所有lua文件中与实际资源文件名匹配,防止因大小写错误导致的游戏崩溃。通过转换文件路径中的斜杠,并用正则表达式匹配,检查引用的资源文件名是否与实际资源文件名一致。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在游戏开发中,客户端写lua代码时,必然会引用res下的各种资源名(png、jpg、json、csb等),在windows上可以忽略资源文件名的大小写,不过在移动平台上是不允许的,如果出现了这样的问题,游戏在移动平台上就会崩掉。

在这样的情况下,我为团队写了工具来处理这样的问题,用到了正则表达式。

先上代码:

import os
import os.path
import re

luaFileRootDir = "./src"
resFileRootDir = "./res"
log_file = "./log.txt"

#store the msg
luaFiles = []
resFiles = []
resFilesQuoted = {}
luaFilesNameDict = {}
special_files = {}

# normal mode
pngRegExString = re.compile(r'[\"\'][\w\s/-]+\.png[\"\']')
jpgRegExString =re.compile(r'[\"\'][\w\s/-]+\.jpg[\"\']')
plistRegExString = re.compile(r'[\"\'][\w\s/-]+\.plist[\"\']')
csbRegExString = re.compile(r'[\"\'][\w\s/-]+\.csb[\"\']')
wavRegExString = re.compile(r'[\"\'][\w\s/-]+\.wav[\"\']')
atlasRegExString = re.compile(r'[\"\'][\w\s/-]+\.atlas[\"\']')
pvrRegExString = re.compile(r'[\"\'][\w\s/-]+\.pvr[\"\']')
jsonRegExString = re.compile(r'[\"\'][\w\s/-]+\.json[\"\']')

def getFilesAbsolutelyPath(ImageFilePath):
    currentfiles = os.listdir(ImageFilePath)
    filesVector = []
    for file_name in currentfiles:
        fullPath = os.path.join(ImageFilePath, file_name)
        if os.path.isdir(fullPath):
            newfiles = getFilesAbsolutelyPath(fullPath)
            filesVector.extend(newfiles)
        else:
            filesVector.append(fullPath)
    return filesVector

def handleBackslash(resFilesVector):
    newFilesVector = []
    for name in resFilesVector:
        newFilesVector.append(name.replace('\\', '/'))
    return newFilesVector

luaFiles = getFilesAbsolutelyPath(luaFileRootDir)
resFilesVector = getFilesAbsolutelyPath(resFileRootDir)
resFiles = handleBackslash(resFilesVector)

def readLuaFile(fileName):
    f = open(fileName, 'r')
    fileContents = f.readlines()
    lineNums = len(fileContents)
    count = 0
    while count < lineNums:
        lineContent = fileContents[count]
        lineNum = count + 1

        pngQuoted = pngRegExString.search(lineContent)
        jpgQuoted = jpgRegExString.search(lineContent)
        plistQuoted = plistRegExString.search(lineContent)
        csbQuoted = csbRegExString.search(lineContent)
        wavQuoted = wavRegExString.search(lineContent)
        atlasQuoted = atlasRegExString.search(lineContent)
        pvrQuoted = pvrRegExString.search(lineContent)
        jsonQuoted = jsonRegExString.search(lineContent)
        quotedStr = "quotedStr"
        if pngQuoted:
            quotedStr = pngQuoted.group()
        elif jpgQuoted:
            quotedStr = jpgQuoted.group()
        elif plistQuoted:
            quotedStr = plistQuoted.group()
        elif csbQuoted:
            quotedStr = csbQuoted.group()
        elif wavQuoted:
            quotedStr = wavQuoted.group()
        elif atlasQuoted:
            quotedStr = atlasQuoted.group()           
        elif pvrQuoted:
            quotedStr = pvrQuoted.group()
        elif jsonQuoted:
            quotedStr = jsonQuoted.group()

        if quotedStr != "quotedStr":
            length = len(quotedStr)
            quotedStr = quotedStr[1:length-1] # remove \"
            resFilesQuoted[quotedStr] = quotedStr
            if luaFilesNameDict.get(quotedStr, -1) == -1:
                luaFilesNameDict[quotedStr] = []
            luaFilesNameDict[quotedStr].append("line: " + '%d'%lineNum + " in \"" + fileName + "\"")
      
        count = count + 1
    f.close()

def matchResFileName(fileQuoted):
    f = open(log_file, 'a')
    quotedRegEx = re.compile(fileQuoted, re.IGNORECASE)
    count = 0
    index = 0
    while index < len(resFiles):
        nameQuoted = quotedRegEx.search(resFiles[index])
        if nameQuoted:
            if 0 != cmp(nameQuoted.group(0), fileQuoted):
                for name in luaFilesNameDict[fileQuoted]:
                    f.write("\"" + fileQuoted + "\" has ignored case in " + name + "\n")
            break
        else:
            count = count + 1
        index = index + 1

    if count == len(resFiles):
        for name in luaFilesNameDict[fileQuoted]:
            f.write("no such res file: " + "\"" + fileQuoted + "\"" + " in " + name + "\n")
    f.close()

for name in luaFiles:
    readLuaFile(name)

f = open(log_file, 'w')
f.close()

# output errors
for name in resFilesQuoted:
    matchResFileName(name)

关于python里的正则表达式, 这篇博客里 已经讲的非常详细了~~我也是参考这里的。

同样,我们先获取到所有的lua文件和所有的资源文件名,在这里需要将资源文件名进行一点处理,因为在lua中引用的文件名如果包含了路径时,肯定使用"/"而不是"\"来表示,而我们在windows上获取到的资源文件名(含有绝对路径)的路径用"\"来划分的,所以我们需要将斜杠换为反斜杠。

然后就可以利用正则表达式进行匹配lua文件里用到的资源文件名了,获取到之后,将当前引用的资源名添加到dict之中,由于该资源文件名可能在多个lua文件中被引用,因此需要再定义一个dict来存放所有引用到该文件名的路径。

完成之后,就可以利用我们获取到的所有引用的资源文件名和原来的资源文件名进行匹配。re.compile(fileQuoted, re.IGNORECASE)表示我们用lua文件中引用的资源名fileQuoted,并且忽略大小写来进行匹配,quotedRegEx.search(resFiles[index])表示我们用编译好的匹配规则在每一个资源文件名中搜寻匹配的串,如果匹配到了,利用cmp来讲引用的资源名和匹配到的文件名进行比较,如果不相等,则表示引用错误; 同时用count变量来判断是否在所有原来的资源文件名中都没有匹配到,这种情况下表示我们在lua文件中引用的资源文件名是不存在的。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值