2013-05-29 65 views
0

我有一个包含超过800万个文件的驱动器,它是CRM系统的文件存储区域。这些文件以特定的格式存储,并且每个文件都应该在数据库中具有匹配的记录。然而,由于一些非常差的安全性,世界和妻子也一直在同一个驱动器上创建文件。我的任务是确定使用Powershell和正则表达式的无效文件。 典型有效的文件路径将会是这个样子:正则表达式需要匹配从文件名派生文件路径的文件路径。

P:\PERSON\06\19\09\619090.5577930.DOC 

所有文件都被称为P驱动的:它包含四个子目录叫:事件OPPORTUN,ORGANISA或个人。其中每一个都包含可变数目的子目录,名称范围从00到99,文件名是由句点分隔的两组数字,后跟扩展名。

我使用匹配这个模式的正则表达式是:

^P:\\(EVENT|OPPORTUN|ORGANISA|PERSON)\\(\d{2}\\)+\d+\.\d+\.\w{3,4}$ 

并发症是有效的文件也具有第一组中的文件名数字,这是子目录路径之间的关系这个:

删除最后一位数字。

如果数字的长度现在是奇数,则添加前导零。

将结果数字分成两对,应该是路径。

因此,使用上面的例子:

第一组数字是:619090

删除最后一个数字:61909

的长度为奇数,以便添加一个前导零:061909

划分成对:06 \ 19 \ 09

我的问题是这个逻辑可以合并到我的正则表达式中,有没有办法使用forward或b ack参考?

回答

0

杰里的回答指出我正确的方向,并发现你可以捕获包含在非捕获组中的组。下面是我的正则表达式连同几个测试:

$samples = @() 
$samples += 'P:\PERSON\06\19\09\619090.5577930.DOC' #good 
$samples += 'P:\PERSON\19\09\19090.5577930.DOC' #good 
$samples += 'P:\PERSON\10\10\10\06\19\09\1010100619090.5577930.DOC' #good 
$samples += 'P:\PERSON\06\19\09\619090a.5577930.DOC' #bad 
$samples += 'P:\PERSON\06\19\09\61909090.5577930.DOC' #bad 
$samples += 'P:\PERSON\06\19\09\6190905577930.DOC' #bad 

$regex = '^P:\\(?:EVENT|OPPORTUN|ORGANISA|PERSON)\\' 
$regex += '(?:(\d)(\d)\\|0(\d)\\)(?:(\d{2})\\)?(?:(\d{2})\\)?(?:(\d{2})\\)?(?:(\d{2})\\)?(?:(\d{2})\\)?' 
$regex += '(?:\1\2|\3)\4?\5?\6?\7?\8?\d?\.\d+\.\w{3,4}$' 

$samples | % { 
    $_ -match $regex 

} 
2

我试图来的东西,如果PowerShell支持反向引用,你可以试试这个:

^P:\\(?:EVENT|OPPORTUN|ORGANISA|PERSON)\\(?:0(\d)|(\d{2}))\\(\d{2})\\(?P<t>\d{2})\\(?:(?:\1|\2)\3\4)0?\.\d+\.\w{3,4}$

\1\4指早期发现,不同的捕捉组。

我测试了一些字符串regex101

唯一的是它也会接受P:\OPPORTUN\61\90\90\619090.5577930.DOC 我不太清楚如何仅用一个正则表达式来解决这个问题......或者使正则表达式比现有的更长(比这可能多两倍)。

它是关于只要如果你想真正做到了两次:

^P:\\(?:EVENT|OPPORTUN|ORGANISA|PERSON)\\0(\d)\\(\d{2})\\(\d{2})\\(?:\1\2\3)0\.\d+\.\w{3,4}|P:\\(?:EVENT|OPPORTUN|ORGANISA|PERSON)\\(\d{2})\\(\d{2})\\(\d{2})\\(?:\4\5\6)\.\d+\.\w{3,4}$

编辑:最多7对数字:

^P:\\(?:EVENT|OPPORTUN|ORGANISA|PERSON)\\(?:0(\d)|(\d\d))\\(?:(\d\d)\\)?(?:(\d\d)\\)?(?:(\d\d)\\)?(?:(\d\d)\\)?(?:(\d\d)\\)?(?:(?:\1|\2)\3?\4?\5?\6?\7?)0?\.\d+\.\w{3,4}

+1

感谢这个,你的解决方案是不完全正确,但我指出了正确的方向,因为我不知道,你可以有非捕获组。 –

+0

@DaveSexton哦!你可能有多次出现的'\ d \ d \ /'。那么,我很高兴能以某种方式获得帮助:)虽然看看你的正则表达式,但通过将'(\ d)(\ d)'分为'(\ d \ d)'和你将只需要一个反向参考为他们每个人:) – Jerry

相关问题