问题描述
我们的动态文件夹结构语法设置如下:
We've a dynamic folder structure syntax set up like:
: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.
Where the words between two colons ':' are variables. Now based on a single path I want to retrieve the projectRoot, parentHierarchy and assetName.
projectRoot 变量和 parentHierarchy 变量允许存在 1 个或多个文件夹,因此它可以包含子文件夹.assetName 变量仅限于单个文件夹.这些是我在下面看到的尝试中定义的.
The projectRoot variable and parentHierarchy variable allow 1 or more folders to be present so it can hold subfolders. The assetName variable is restricted to a single folder. These are the defined as in my try seen below.
假设我通过了:
C:/Projects/foo/dev/model/props/furniture/couch/data/
这应该返回:
projectRoot = C:/Projects/foo/
parentHierarchy = props/furniture
assetName = couch
然后我们还可以检查规则集中定义的所有路径是否都存在(但这相对容易):
Then we could also check whether all of the paths defined in the rule set exist (but that's relatively easy):
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
这是我当前的测试实现:
Here's my current test implementation:
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""")
目前它只找到由静态部分组成的路径(未检查变量规则,我不确定如何在此处添加).
Currently it only finds path consisting of the static parts (the variable rules aren't checked, I'm not sure how to add that in here).
它不会从任何遵循规则的完整路径中解析出变量.
And it doesn't parse out the variables from any full path that follows the rule.
推荐答案
我认为你可以用一个正则表达式来完成:
I think you can do it all with one regex:
In [24]: re.search(r'(.+)(?:dev/model/|asset/shots/)(.+)/(.+?)(?:/data|/scenes)', path).groups()
Out[24]: ('C:/Projects/foo/', 'props/furniture', 'couch')
这篇关于根据预定义的文件夹结构找回文件夹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!