2016-09-27 112 views
1

我试图从一个目录,它的文件名遵循这种模式获得的文件列表:Python的正则表达式数字和下划线

PREFIX_YYYY_MM_DD.dat 

例如

FOO_2016_03_23.dat 

似乎无法得到正确的正则表达式。我试过以下内容:

pattern = re.compile(r'(\d{4})_(\d{2})_(\d{2}).dat') 
>>> [] 

pattern = re.compile(r'*(\d{4})_(\d{2})_(\d{2}).dat') 
>>> sre_constants.error: nothing to repeat 

正则表达式对我来说肯定是一个弱点。任何人都可以解释我要去哪里错了吗?

要获得这些文件,我在做:

files = [f for f in os.listdir(directory) if pattern.match(f)] 

PS,我怎么会允许的.dat和.DAT(不区分大小写文件扩展名)?

感谢

+0

你是什么意思“逃避”呢? –

+0

尝试're.compile(r'(?i)\ d {4} _ \ d {2} _ \ d {2} \。dat $')'然后'if pattern。搜索(f)' –

+0

当我添加转义字符时,更改为搜索时修复了我的解决方案,谢谢 –

回答

2

你有两个问题与你的表达: re.compile(r'(\d{4})_(\d{2})_(\d{2}).dat')

第一个,作为之前的评论说,就是.dat前权应通过将前一个反斜杠(\)进行转义。否则,python会将它视为一个特殊字符,因为在正则表达式中,.表示“任何字符”。

除此之外,您并未处理表达式的大写异常。您应该为datDAT作出可能的选择。

并有了两个变化,它应该看起来像:

re.compile(r'(\d{4})_(\d{2})_(\d{2})\.(?:dat|DAT)')

作为一个额外的说明,我在组的开头加入?:所以正则表达式匹配的结果忽略它。

+0

谢谢。你能否澄清“正则表达式匹配器在结果中忽略它”? –

+1

@AdamHughes:忽略此解释:)这只是一个非捕获组,这是一个用于分组而不将值存储在组缓冲区中的构造。 –

1

使用pattern.search()而不是pattern.match()

pattern.match()始终与字符串(包括PREFIX)的起始处匹配。 pattern.search()搜索字符串中的任何地方。

+0

好的,谢谢,我明白了澄清 –

1

这是做你想做的吗?

>>> import re 
>>> pattern = r'\A[a-z]+_\d{4}_\d{2}_\d{2}\.dat\Z' 
>>> string = 'FOO_2016_03_23.dat' 
>>> re.search(pattern, string, re.IGNORECASE) 
<_sre.SRE_Match object; span=(0, 18), match='FOO_2016_03_23.dat'> 
>>> 

它看起来与您给出的字符串格式相匹配。

+0

是的,这工作表示感谢。将尝试消化它。 \ Z是什么? –

+0

即使没有第一个\ A [az],它也能正常工作 –

+0

如果您想了解它的功能,请运行以下命令:'re.compile(pattern,re.DEBUG)' –

1

以下内容应符合您的要求。

[^_]+[_]\d{4}[_]\d{2}[_]\d{2}[\.]\w+ 

我建议使用在未来https://regex101.com/(Python的正则表达式)或http://regexr.com/(JavaScript的正则表达式),如果你想验证你的正则表达式。

+0

感谢这个资源。 –

+1

@AdamHughes:不要使用regexr,因为它只支持JavaScript正则表达式。使用regex101.com,debuggex.com以及许多其他支持Python're'的程序。 –

+0

编辑,谢谢@WiktorStribiżew – PrestonM