PowerShell与正则表达式匹配的字符串

问题描述:

我正在处理一个脚本,将电视节目转移到我的驱动器上相应的文件夹中。我遇到了将节目与其文件夹相匹配的问题。这是我有一个问题的代码片段:PowerShell与正则表达式匹配的字符串

#Remove all non-alphanumeric characters from the name 
$newname = $Episode.Name -replace '[^0-9a-zA-Z ]', ' ' 

#Split the name at S01E01 and store the showname in a variable (Text before S01E01) 
$ShowName = [regex]::Split($newname, 'S*(\d{1,2})(x|E)')[0] 

#Match and get the destination folder where the names are similar 
################## THIS IS WHERE THE ISSUE IS ####################### 
$DestDir = Gci -Path $DestinationRoot | Where { $ShowName -like "*$($_.Name)*" } | foreach {$_.Name } 

例如,一个名为秀“神秘博士2005 S02E02牙齿和Claw.mp4”没有返回一个类似文件夹,命名为“DoctorWho ”。

问题: 我可以修改$ DestDir以便我可以匹配名称?有没有更好的方法来做到这一点?

工作代码:从测试输出

# Extract the name of the show (text before SxxExx) 
$ShowName = [regex]::Split($Episode.Basename, '.(\d{1,3})(X|x|E|e)(\d{1,3})')[0] 

# Assumption: There is a folder in TV shows directory that is named correctly, and the input file is named correctly 
# Try to match by stripping all non-Alphabet characters from both names and check if the folder name contains the file name 
$Folder = gci -Path $DestinationRoot | 
      Where {$_.PSisContainer -and ` 
      (($_.Name -replace '[^A-Za-z]','') -match ($ShowName -replace '[^A-Za-z]','')) } | 
      select -ExpandProperty fullname 

一些示例:

Input file name: Arrow S01E02.mp4 
Show name:   Arrow 
Matching folder: C:\Users\Public\Videos\TV Shows\Arrow 
----------------------------------------------------------------------- 
Input file name: Big Bang Theory S3E03.avi 
Show name:   Big Bang Theory 
Matching folder: C:\Users\Public\Videos\TV Shows\The Big Bang Theory 
----------------------------------------------------------------------- 
Input file name: Doctor Who S08E03.mp4 
Show name:   Doctor Who 
Matching folder: C:\Users\Public\Videos\TV Shows\Doctor Who (2005) 
----------------------------------------------------------------------- 
Input file name: GameOfThronesS01E01.mp4 
Show name:   GameOfThrones 
Matching folder: C:\Users\Public\Videos\TV Shows\Game Of Thrones 
----------------------------------------------------------------------- 
+0

请原谅我陈述明显,但为什么你不确定文件夹是否符合节目名称,即将“DoctorWho”重命名为“Doctor Who 2005”? PowerShell不知道你的“类似”的想法是什么,你必须说明每个案例。你可以做的一件事是添加'.Trim()',这样开始和结束处的空格都被删除了,但是你必须明确地说出进一步的转换。 – 2014-10-20 15:31:29

+0

@JeroenMostert这对我来说很合适。但是,我已经计划在完成后与其他人分享。我不确定他们的设置是什么样的,所以我试图让它尽可能通用。 – 2014-10-20 15:37:01

+0

好吧,你可以做一些事情,比如“去掉所有的空格和尾部的数字,并显示名字和文件夹名称,然后开始匹配”,但似乎很可能无论你做什么,有人会抱怨说它不能正常工作。至少简单的算法有一个好处,人们可以理解发生了什么。 – 2014-10-20 15:45:50

使用,你要弄清楚什么节目名称是基于你的建议的方法相同。随着Doctor Who 2005 S02E02 Tooth and Claw.mp4

$showName = $Episode -replace '[^0-9a-zA-Z ]' 
$showName = ($showName -split ('S*(\d{1,2})(x|E)'))[0] 
$showName = $showName -replace "\d" 

我增加了行$showName = $showName -replace "\d"考虑在本赛季的一年。如果节目中间包含一个数字,但应该适用于大多数情况,这是一个警告。继续进行$DestDir的确定。部分问题是你有你的Where比较倒退。您想要查看节目名称是否是潜在文件夹的一部分,而不是其他方式。另外,由于潜在的文件夹可能包含空格,因此共同性也应该包含该假设。

Get-ChildItem -Path $DestinationRoot -Directory | Where-Object { ($_.name -replace " ") -like "*$($showName)*"} 

我会去使用Choice选择让用户确认文件夹,因为它可能有多个匹配。我想指出的是,可能很难说明所有的命名约定和差异,但是你拥有的是一个好的开始。

+0

我完成了一些类似于你所建议的事情。我做了一个包含,而不是一个像。至于选择,我已经决定脚本将发送电子邮件给用户让他们知道有文件不匹配,这将需要手动干预。谢谢您的帮助! – 2014-10-20 20:06:35

+0

@Kevin_'-contains'只适用于数组。在'where-object'中你不会使用数组。供参考 – Matt 2014-10-20 20:17:59

+0

哎呀,意思是说 - 匹配。 – 2014-10-20 20:23:22