问题描述
- 艺术家 - 歌曲(feat.OtherArtist)(feat.OtherArtist).mp4
- 艺术家 - 歌曲(feat.OtherArtist)(电台编辑)(feat.OtherArtist).mp4
Get-ChildItem -Path "path" -Recurse -Filter *feat*feat* | ForEach-Object { $_ | Rename-Item -NewName $_.Name.SubString(0,$_.Name.Length -10) }
这会获取所有具有重复特征的文件,然后仅删除最后 10 个字符(不幸的是包括文件扩展名),如果歌曲具有多个艺术家甚至名称更长的艺术家,这显然不起作用。
我想为此我需要正则表达式,但我顶多还是一个使用 Powershell 的初学者,所以我真的很感谢您的帮助。
解决方法
RegEx 确实可以为所欲为。你只需要做一些与你在第一个过滤器中所做的非常相似的事情。这是魔法字符串:
(.*feat.*?)(\s*\(?feat.*\)\s*)(\..+)
您可以像这样使用它(完全跳过 ForEach
循环):
Get-ChildItem -Path .\* -Recurse -Filter *feat*feat* | Rename-Item -NewName {$_.Name -replace '(.*feat.*?)(\s*\(?feat.*\)\s*)(\.[^\.]+)','$1$3'}
这里是这个字符串是如何分解的,以及它的作用:
(.*feat.*)(\s\(feat.*\)\s*)(\.[^\.]+)
第一捕获组 (.feat.)
.匹配任何字符(行终止符除外)
* 匹配前一个令牌在零次和无限次之间,尽可能多次,根据需要回馈(贪婪)
feat 字面上匹配字符 feat(区分大小写)
.匹配任何字符(行终止符除外)
*?在零次和无限次之间匹配前一个令牌,尽可能少,根据需要扩展(懒惰)
第二捕获组 (\s(feat.)\s)
\s 匹配任何空白字符(相当于 [\r\n\t\f\v ])
* 匹配前一个令牌在零次和无限次之间,尽可能多次,根据需要回馈(贪婪)
( 匹配字符 ( 字面意思 (区分大小写)
?匹配0到1次之间的前一个token,尽可能多次,根据需要回馈(贪婪)
feat 字面上匹配字符 feat(区分大小写)
.匹配任何字符(行终止符除外)
* 匹配前一个令牌在零次和无限次之间,尽可能多次,根据需要回馈(贪婪)
) 字面上匹配字符 )(区分大小写)
\s 匹配任何空白字符(相当于 [\r\n\t\f\v ])
* 匹配前一个令牌在零次和无限次之间,尽可能多,根据需要回馈(贪婪)
第三个捕获组 (\.[^\.]+)
\.匹配字符。字面意思(区分大小写)
匹配以下列表中不存在的单个字符 [^\.]
+ 匹配一次和无限次之间的前一个令牌,尽可能多次,根据需要回馈(贪婪)
看到它在这里工作(我从那里得到字符串分解,但格式更好):https://regex101.com/r/FWlNLi/1