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

2 つのコロン ':' の間の単語は変数です。ここで、1 つのパスに基づいて、projectRoot、parentHierarchy、および assetName を取得します。

projectRoot 変数と parentHierarchy 変数を使用すると、1 つ以上のフォルダーを存在させることができるため、サブフォルダーを保持できます。assetName 変数は、1 つのフォルダーに制限されています。これらは、以下に示す私の試みのように定義されています。

だから私が渡すとしましょう:

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

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 に答える