我有一个工作正则表达式,它给了我想要的结果,但它不包含它需要的安全性。 (防呆)
让我们说我有一个匹配路径部分的正则表达式,类似于:
import re
path = "C:/Projects/foo/dev/model/props/furniture/couch/data/fbx"
regex = re.compile("(.+)/dev/model/(.+)/(.+)/data/fbx")
m = regex.search(path)
if m:
print m.groups()
# ('C:/Projects/foo', 'props/furniture', 'couch')
我希望能够使用匹配一个或多个文件夹的内容替换匹配任何字符,直到正则表达式的以下部分。
假设我们将一个简单的文件夹定义为单词字符(无或多个),以斜杠结尾:
[\w]*/
我想将0到10组合在一起,我该怎么做?
在我看来,我有类似的东西(请注意,这不起作用!):
# match any number of word characters ending with a slash zero to ten times
([[\w]*/]{0,10})
# match any number of word characters ending with a slash zero to one time
([[\w]*/]?)
编辑:
根据RedBaron和jamylak的回答,我想出了以下内容:
((?:[:\w]+/){0,3})
这将以0到三个出现的[:\ w]字符分组,以斜杠'/'结尾。使用?:在组的开头,它不会被发送回匹配的分组。然而,结合它们的外部团体是。因此,我们只能获得完全分组的结果。
唯一的问题是我希望最后一部分也可能匹配一个文件。 (所以不要以斜线结尾。)我甚至更喜欢在没有正则表达式的尾部斜线的情况下将其恢复,但我也可以轻松地删除结果的末尾。
非常感谢任何反馈。如果这是要走的路,我会将其添加为答案。
编辑:
与Finding folders back based on a predefined folder structure
有关UPDATE /编辑:
基于到目前为止给出的所有答案,我已经提出了各种各样的尝试,但最终它们的结果都非常缓慢。
import re
path = "C:/Projects/foo/dev/model/props/furniture/couch/data/fbx"
regex = re.compile(r"""((?:^(?:[\w:]+/?)+)|(?:(?<=/)(?:[\w]+/?)+))/dev/model/""")
print 'search start'
m = regex.search(path)
print 'search done'
if m:
print 'match', m, m.groups()
else:
print 'no match'
我不完全确定如何加快速度!
答案 0 :(得分:2)
正则表达式中的[]
不会对正则表达式进行分组。它用于指定字符类。
也许这会奏效 -
\w*/{0,10}
对于分组,只需使用()
(\w*/){0,10}
修改强>
根据您编辑的问题,我认为您想要的是0-3次出现的目录名称匹配,然后文件名也匹配。
假设文件名中只有字母(以及可选的最多三个字符的扩展名)
^((?:[:\w]+/){0,3})(\w+(?:\.\w{1,3})?)?$
这是非常大的,但可以分为两部分
这就是你已经拥有的
((?:[:\w]+/){0,3})
我添加的内容
(\w+(?:\.\w{1,3})?)?
这是最后的可选文件名。 (如果它不是可选的,您可以删除最后一个?
)。文件名本身既可以由字母组成,也可以包含最多3个字符的扩展名
添加^
和$
将停止激烈的匹配
>>> pat=re.compile('^((?:[:\w]+/){0,3})(\w+(?:\.\w{1,3})?)?$')
>>> my_str='fwefw/wfwf/wefwf/dde.cdf'
>>> pat.search(my_str).groups()
('fwefw/wfwf/wefwf/', 'dde.cdf')
>>> my_str='fwefw/dde.cdf'
>>> pat.search(my_str).groups()
('fwefw/', 'dde.cdf')
答案 1 :(得分:1)
而不是这个,由于catastrophic backtracking确实非常缓慢,
((?:^(?:[\w:]+/?)+)|(?:(?<=/)(?:[\w]+/?)+))/dev/model/
试试这个
(^[\w:]+(?:/\w+)*|(?<=/)\w+(?:/\w+)*)/dev/model/
或者
(^[\w:]+[\w/]*|(?<=/)[\w/]+)/dev/model/
您可能需要考虑使用re.match
首先验证字符串的方法以及(\w:)?(/\w+)+$
等模式
然后,当您可以预期某个结构时,您可以使用更简单的正则表达式来提取数据:
/?([^/]*(?:/[^/]+)*)/dev/model/
答案 2 :(得分:0)
您不能像[]
一样将[]
放在([[\w]*/]{0,10})
内>>> re.match(r'(\w*/){0,10}', 'abc/def/ghi/').group()
'abc/def/ghi/'
。相反,你想用括号分组。
试试这个:
{{1}}