查找正确的正则表达式以找到一组数字是不确定的

时间:2017-03-22 15:50:21

标签: regex powershell

我有一个分层文件夹结构,它基于一个nestes资产/项目层次结构。

  • 顶级资产的ID为Foo (22)。 (2 - n个数字 - 括在括号中)
  • 等级2然后如下所示:Foo (22^108)(2组2-n数字除以^并括在括号中)
  • 等级3:Foo (22^108^1771)
  • 等级4:......
  • 等级5:......
  • 项目级别:由{paranthesis
  • 包围的(^123) ^ + 2-n个数字

我需要遍历此文件夹结构,并将某些层次结构级别移动到其他目的地。

要确定我当前在哪个级别上以及当前文件夹需要移动的位置,我想使用正则表达式。

我已经准备好了1到4级和项目级别的表达式,但是5级是不确定的,我无法弄清楚原因。

给出以下两个例子(Demo):

  1. 等级4(22 ^ 108 ^ 581 ^ 2116)
  2. Foo,Kings Road Level 5(22 ^ 108 ^ 581 ^ 2116 ^ 7310)
  3. 正则表达式\((?<!\^)(\d{2,}\^{0,1}){4}(?!\^)\)仅匹配4级资产,这是正确的。 级别5的正则表达式类似:\((?<!\^)(\d{2,}\^{0,1}){5}(?!\^)\) - 我将捕获组的数量从4增加到5,但根据正则表达式,它匹配级别4和5,这不应该发生。 所以目标是匹配以下模式:

    1. 左括号
    2. 5组2到n位
    3. 这些团体分为一个Caret
    4. 第一组必须没有领先的Caret
    5. 最后一组不得有尾随的Caret
    6. 关闭括号
    7. 我做错了什么?

      PS:如果它有任何重要性。这些文件夹位于SharePoint文档库中,代码将在Powershell中运行。

1 个答案:

答案 0 :(得分:2)

您无需像过去那样担心标准4和5。只要前面的括号后跟数字,最后一个括号也跟数字一起,你应该没问题。

\((\d{2,}\^){4}\d{2,}\)

匹配外侧括号以及4组数字和尾随插入符号以及最后一组数字。如果您希望匹配级别3,则在上述正则表达式中将4更改为2。

有一些领先或尾随的插入符号,它们是不匹配的。

命名匹配

根据您以后使用这些值的方式,查看PowerShell中的命名匹配可能会有所帮助。我们要做的是根据您尝试匹配的级别数构建自定义正则表达式匹配字符串。

$matchNumberOfLevels = 5
$regex = "\(" + 
    ((1..($matchNumberOfLevels-1) | ForEach-Object{"(?<level$_>\d{2,})\^"}) -join "") +
    "(?<level$matchNumberOfLevels>\d{2,})\)"

"Foo, Kings Road Level 5 (22^108^581^2116^7310)" -match $regex

对于每个级别(上例中的1到5),我们创建一个名为level_n_的命名匹配,其中 n 是插入符分隔数字的位置。那么我们你看一下你会得到命名匹配的匹配项,你可以在以后的代码中使用它们。

$matches

Name                           Value                                                                                                 
----                           -----                                                                                                 
level3                         581                                                                                                   
level2                         108                                                                                                   
level4                         2116                                                                                                  
level5                         7310                                                                                                  
level1                         22                                                                                                    
0                              (22^108^581^2116^7310) 

$matches.level1
22

很酷但可能太过分了。

拆分结果

一个简单的修剪和分割会得到一些类似的东西,而不是花哨的名字。

$matchNumberOfLevels = 5
"Foo, Kings Road Level 5 (22^108^581^2116^7310)" -match "\((\d{2,}\^){$($matchNumberOfLevels - 1)}\d{2,}\)"
$levels = $Matches[0].Trim("()") -split "\^"
$levels[0]

所以$levels是一个数组,其中有5个元素对应于你的系统级别。

请注意,此逻辑仅针对1级匹配失败。