0

我们设置了一个动态文件夹结构语法,如下所示:

:projectRoot:/dev/model/:parentHierarchy:/:assetName:/data/obj
:projectRoot:/dev/model/:parentHierarchy:/:assetName:/data/fbx
:projectRoot:/asset/shots/:parentHierarchy:/animation/:assetName:/scenes
:projectRoot:/asset/shots/:parentHierarchy:/rendering/:assetName:/scenes

其中两个冒号“:”之间的单词是变量。现在基于单个路径,我想检索 projectRoot、parentHierarchy 和assetName。

projectRoot 变量和 parentHierarchy 变量允许存在 1 个或多个文件夹,因此它可以包含子文件夹。assetsName 变量仅限于单个文件夹。这些是我在下面看到的尝试中定义的。

所以假设我传入:

C:/Projects/foo/dev/model/props/furniture/couch/data/

这应该返回:

projectRoot = C:/Projects/foo/
parentHierarchy = props/furniture
assetName = couch

然后我们还可以检查规则集中定义的所有路径是否都存在(但这相对容易):

C:/Projects/foo/dev/model/props/furniture/couch/data/obj
C:/Projects/foo/dev/model/props/furniture/couch/data/fbx
C:/Projects/foo/asset/shots/props/furniture/animation/couch/scenes
C:/Projects/foo/asset/shots/props/furniture/rendering/couch/scenes

这是我当前的测试实现:

import os
import re

variableRegex = re.compile(":[\w]*:")

def getRules():
    return [":projectRoot:/dev/model/:parentHierarchy:/:assetName:/data/obj",
            ":projectRoot:/dev/model/:parentHierarchy:/:assetName:/data/fbx",
            ":projectRoot:/asset/shots/:parentHierarchy:/animation/:assetName:/scenes",
            ":projectRoot:/dev/model/:parentHierarchy:/:assetName:/data/obj"]

def getVarRules():
    """
        These rules define how many hierarchy depth each variable represents.
        (This is simplified from the actual code I'm working with to ease the example for the question)

        -1 defines that the variable can hold one or more folders (nested folders), thus never zero
        1 defines it will can't have subfolders and will define a single folder
    """
    return {":projectRoot:": -1,
            ":parentHierarchy:": -1,
            ":assetName:": 1}

def reversePath(path, rule):
    """
        Returns the variables within rule by getting them from the path.
        This will only work if the given path is valid for the given rule.

        This is currently a dummy function.
        This is a part where I get stuck. How to slice it up based on the rules?
    """
    varHierarchyDepth = getVarRules()
    return path

def reverseEngineerWorkspaces(path):
    """
        This function should check if the given path is valid for any of the rules.

        Note that static parts (end parts of the rule not defined by a variable) may be omitted from the input path.
        That input path can still be validated (only if the folder exists and contains the required static end as
        subdirectories/files.)
    """
    rules = getRules()
    varHierarchyDepth = getVarRules()

    path = os.path.realpath(path)
    path = path.replace("\\","/")   # force forward slashes so it's similar to our rules definitions.
    path = path.rstrip("/")         # remove any trailing slashes

    for rule in rules:
        # 1.
        # First we check if any of the static parts that are in front of the last variables are present in the path.
        # If not present it certainly isn't the correct path.
        # We skip checking the end static part because we could easily check whether those exist within the current folder
        staticParts = [ part for part in variableRegex.split(rule) if part != "" and part != "/" ]
        if not all([x in path for x in staticParts[:-1]]):
            continue

        if rule.endswith(staticParts[-1]):
            # If this this rule ends with a static part we can use that to check if the given path is fully valid
            # Or if the path concatenated with that static part exists. If so we have a valid path for the rule.
            if path.endswith(staticParts[-1]):
                return reversePath(path, rule)
            else:
                lastPartSubfolders = staticParts[-1].split("/")
                for x in range(len(lastPartSubfolders)):
                    tempPath = os.path.join(path, *lastPartSubfolders[:-x])
                    if os.path.exists(tempPath):
                        return reversePath(tempPath, rule)
        else:
            raise NotImplementedError("There's no implementation for rules without a static end part.")

print reverseEngineerWorkspaces("""C:/Projects/foo/dev/model/props/furniture/couch/data/""")
print reverseEngineerWorkspaces("""C:/Projects/foo/dev/model/props/furniture/couch/data/fbx""")
print reverseEngineerWorkspaces("""C:/Projects/foo/dev/model/props/furniture/couch/data/obj""")
print reverseEngineerWorkspaces("""C:/Projects/foo/asset/shots/props/furniture/animation/couch/scenes""")

目前它只找到由静态部分组成的路径(未检查变量规则,我不确定如何在此处添加)。

并且它不会从遵循规则的任何完整路径中解析出变量。

4

1 回答 1

1

我认为您可以使用一个正则表达式完成所有操作:

In [24]: re.search(r'(.+)(?:dev/model/|asset/shots/)(.+)/(.+?)(?:/data|/scenes)', path).groups()
Out[24]: ('C:/Projects/foo/', 'props/furniture', 'couch')
于 2013-03-20T18:45:11.003 回答