使用正则表达式匹配的组

时间:2018-02-20 15:12:27

标签: regex powershell

我正在努力编写执行以下操作的Powershell Command。假设一个文件夹中有一堆文件,其随机名称与正则表达式模式匹配。我想捕获匹配模式的部分,并仅将文件重命名为该部分。

E.g。 " asdjlk-c12aa13-.PDF"应成为" c12aa13.pdf"如果模式为\w\d+\w+\d+(或类似)。

我目前的想法是这样的:

Get-ChildItem | Rename-Item -NewName { $_.Name -match $pattern ... } -WhatIf

其中...需要替换为设置"值"代码块(即NewName)到匹配组。即我不知道如何在$matched命令后直接访问-match

另外,我想知道是否可以使用-match进行延迟匹配,.*?似乎无法做到这一点。

4 个答案:

答案 0 :(得分:1)

虽然您可以按照-match操作,然后通过自动$Matches变量提取匹配的部分,但通常更容易合并-replace运算符的帮助下执行这两项操作:

您只需确保为了仅返回感兴趣的部分,您必须匹配输入字符串完整,然后忽略您不关心的部分:< / p>

PS> 'asdjlk-c12aa13-.pdf' -replace '^.*?(\w\d+\w+\d+).*?(\.pdf)$', '$1$2'
c12aa13.pdf
  • ^.*?(懒惰地)匹配感兴趣部分之前的前缀。

  • (\w\d+\w+\d+)匹配感兴趣的部分,包含在捕获组中;因为它是正则表达式中的 1st 捕获组,所以您可以在替换操作数中引用它捕获的$1

  • .*?(懒惰地)匹配.pdf文件扩展名后的所有内容。

  • (\.pdf)$匹配名称末尾的文件扩展名.pdf,并且作为 2nd 捕获组,可以引用为$2 in替换操作数。

  • $1$2简单地连接2个捕获组匹配项以输出所需的名称。

    • 注意:通常,对正则表达式和替换操作数使用单引号字符串,以便 PowerShell意外解释$ 事先。

    • 有关-replace的更多信息以及替换操作数的语法,请参阅我的this answer

您的命令上下文中的解决方案:

Get-ChildItem |
  Rename-Item -NewName { $_.Name -replace '^.*?(\w\d+\w+\d+).*?(\.pdf)$', '$1$2' } -WhatIf

答案 1 :(得分:0)

说实话,我不确定您的上述行是否有效。如果&#34; \ w \ d + \ w + \ d +&#34;是你正在寻找的模式,我会做这样的事情:

[regex]$regex = "\w\d+\w+\d+"    
Get-ChildItem | ?{$_.name -match $regex} | %{rename-item $_ "$($regex.Matches($_).value).pdf"}

在这种情况下,您将Get-ChildItem的输出传递给&#34; foreach where loop&#34; (?{...}),之后你将这个outpout传递给&#34; foreach循环&#34; (%{...})重命名每个对象。

答案 2 :(得分:0)

您可以在脚本块中放入任意数量的内容。还隐藏-match的输出。正则表达式对“?”很懒。

Get-ChildItem | Rename-Item -NewName { [void]($_.Name -match '.+?'); $matches.0 } -WhatIf

What if: Performing the operation "Rename File" on target "Item: /Users/js/foo/afile Destination: /Users/js/foo/a".
What if: Performing the operation "Rename File" on target "Item: /Users/js/foo/bfile Destination: /Users/js/foo/b".
What if: Performing the operation "Rename File" on target "Item: /Users/js/foo/cfile Destination: /Users/js/foo/c".

答案 3 :(得分:0)

一种更安全的方法是通过测试(类似于-WhatIf) 本示例从DSC12345 - X-1.jpg => DSC12345-X1.jpg

重命名文件
# first verify what your files will convert too
# - gets files
# - pipes to % (foreach)
# - creates $a variable for replacement
# - echo replacement
Get-ChildItem . | % { $a = $_.name -replace "^DSC(\d+)\s-\s([A-Z])-(\d).jpg$",'DSC$1-$2$3.jpg'; echo "$_.name => $a"; }

# example output:
# DSC04975-W1.jpg.name => DSC04975-W1.jpg
# DSC04976-W2.jpg.name => DSC04976-W2.jpg
# DSC04977-W3.jpg.name => DSC04977-W3.jpg
# ...

# use the same command and replace "echo" with "ren"
Get-ChildItem . | % { $a = $_.name -replace "^DSC(\d+)\s-\s([A-Z])-(\d).jpg$",'DSC$1-$2$3.jpg'; ren $_.name $a; }

这更安全,因为如果运行不正确,重命名会造成灾难性的后果。