0

我有一个包含超过 800 万个文件的驱动器,它是 CRM 系统的文件存储区域。这些文件以特定格式存储,并且每个文件都应在数据库中具有匹配的记录。然而,由于一些非常糟糕的安全性,世界和妻子也一直在同一驱动器上创建文件。我的任务是使用 Powershell 和正则表达式识别我正在执行的无效文件。典型的有效文件路径如下所示:

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

所有文件都位于名为 P: 的驱动器上,其中包含四个子目录:EVENT、OPPORTUN、ORGANISA 或 PERSON。其中每一个都包含可变数量的子目录,其名称范围从 00 到 99,文件名是由句点分隔并后跟扩展名的两组数字。

我用来匹配此模式的正则表达式是:

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

复杂之处在于,有效文件还具有文件名中的第一组数字与子目录路径之间的关系,即:

删除最后一个数字。

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

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

所以使用上面的例子:

第一组数字是:619090

去掉最后一位:61909

长度为奇数,因此添加前导零:061909

分成对:06\19\09

我的问题是这个逻辑可以合并到我的正则表达式中,有没有办法使用前向或后向引用来做到这一点?

4

2 回答 2

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}

于 2013-05-29T14:51:07.590 回答
0

Jerry 的回答为我指明了正确的方向,并发现您可以将捕获组包含在非捕获组中。下面是我的正则表达式和一些测试:

$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

}
于 2013-05-30T09:34:19.500 回答