Regex 使用正则表达式匹配组重命名Powershell

Regex 使用正则表达式匹配组重命名Powershell,regex,powershell,Regex,Powershell,我正在努力编写一个Powershell命令来执行以下操作。假设有一个文件夹,其中包含一组随机名称与正则表达式模式匹配的文件。我想捕获与模式匹配的部分,并仅将文件重命名为该部分 例如,如果模式为\w\d+\w+\d+(或类似模式),则“asdjlk-c12aa13-.pdf”应变为“c12aa13.pdf” 我目前的想法是这样的: [regex]$regex = "\w\d+\w+\d+" Get-ChildItem | ?{$_.name -match $regex} | %{renam

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

例如,如果模式为
\w\d+\w+\d+
(或类似模式),则“asdjlk-c12aa13-.pdf”应变为“c12aa13.pdf”

我目前的想法是这样的:

[regex]$regex = "\w\d+\w+\d+"    
Get-ChildItem | ?{$_.name -match $regex} | %{rename-item $_ "$($regex.Matches($_).value).pdf"}
getchilditem |重命名Item-NewName{$\.Name-match$pattern…}-WhatIf

其中,
需要替换为将代码块(即新名称)的“值”设置为匹配组的内容。也就是说,我不知道如何在
-match
命令之后直接访问
$matched


另外,我想知道是否有可能使用
-match
进行惰性匹配,
*?
似乎不起作用。

老实说,我不确定上面的行是否有效。如果您要查找的模式是“\w\d+\w+\d+”,我会这样做:

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

在这种情况下,您将Get ChildItem的输出管道化到“foreach where loop”(?{…}),然后将此输出管道化到“foreach loop”({…})以重命名每个对象。

同时您可以按照
-match
操作进行后续匹配部分的提取通过自动
$Matches
变量,在
-replace
操作符的帮助下,通常更容易组合这两个操作:

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

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

  • (\w\d+\w+\d+
    匹配封装在捕获组中的感兴趣部分;由于它是正则表达式中的第一个捕获组,您可以在替换操作数中将它捕获的内容称为
    $1

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

  • (\.pdf)$
    匹配名称末尾的文件扩展名
    .pdf
    ,作为第二个捕获组,可以在替换操作数中引用为
    $2

  • $1$2
    只需将两个捕获组匹配项串联起来,即可输出所需名称

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

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


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

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

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


更安全的方法是通过测试(类似于
-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; }

这是非常安全的,因为如果运行不正确,重命名可能会带来灾难性后果。

对于正则表达式,您可以在一个组中捕获您想要的内容,并在替换中使用这些组,这正是我的想法,是的。powershell带来了更多的问题:/Heh。。。与正则表达式匹配的随机名称。我不确定你是否知道“随机”是什么意思@当然,艾伯格林可能用词不当。随机性是指文件名中的随机部分不受模式控制,模式可以是任何东西,构成模式的符号可以是随机的。