我首先想开始说我非常喜欢阅读来自这个社区的建议及其提供的内容。我提前感谢您花时间阅读我的问题以及可能提供的任何意见。我不想让别人简单地为我编写代码,但也许有人可以提供一些我可能没有考虑过的技巧。
问题:
我的任务是协助我们的网络开发人员 更正一些过时的文件/项目名称并将它们对齐 他们新采用的命名标准。
示例:
在众多文件夹结构中,我们有文件名,例如 以下:
Project.Name.J72e49q2F7-FileName.txt
文本文件扩展名只是一个示例。我正在测试我的功能,我需要更改的扩展名将在以后更改我们的合法数据时予以纠正。
我想要完成的任务:
我知道在连字符之前总会有一部分 潜力"未知"已定义字符的数量(即: "
J72e49q2F7
"一部分)。我需要突破这部分文本 所以我可以将它改为全部大写,类似于TOUPPER()
所做的。还有其他各种视觉变化 对于他们想要完成的名字,我已经能够解决,我被困住了 确定如何解决这一部分。
研究结果我考虑过使用:
我已经尝试了一些方法。我的假设是 MAYBE REGEX可以处理这个,但我对使用REGEX非常新。我也有一种感觉,可能有一种简单的方法可以使用
split()
命令将文本分开,然后将其重新组合在一起。
我现在的职能:
Function Fix-Filenames {
Param(
[Parameter(Position = 0, Mandatory = $true)]
[string] $folderpath
)
##Capitalize first letter of each word
$TextInfo = (Get-Culture).TextInfo
Get-ChildItem -path $folderpath -Filter *.txt | foreach { $NewName = $TextInfo.ToTitleCase($_); ren $_.FullName $NewName }
##Replace periods with spaces
Get-ChildItem -path $folderpath -Filter *.txt | Rename-Item -NewName { $_.BaseName.replace("."," ") + $_.Extension }
##Replace hyphens with space/hyphens
Get-ChildItem -path $folderpath -Filter *.txt | Rename-Item -NewName { $_.BaseName.replace("-"," - ") + $_.Extension }
##Correct Mid-Section of Project Names##
##??? Maybe a split string here? Maybe Regex?
}
答案 0 :(得分:2)
我的回答是你提到的RegEx解决方案。这是令人惊讶的长,因为我只是一个接一个地链接了所有的替换程序,并添加了一个删除双空格,以防万一你遇到像“Project - Name.As2SAS543x-FileName.txt”之类的名称,在这种情况下更换“ - ”和“ - ”会以双倍空格结束。
Function Fix-Filenames {
Param(
[Parameter(Position = 0, Mandatory = $true)]
[string] $folderpath
)
$TextInfo = (Get-Culture).TextInfo
Get-ChildItem -path $folderpath -Filter *.txt | Where {$_.BaseName -Match "(.+?\.)([^.]+?)(-.*)"} | foreach { $NewName = $TextInfo.ToTitleCase(($Matches[1]+$Matches[2].ToString().ToUpper()+$Matches[3])).replace("."," ").replace("-"," - ").replace(" "," ")+$_.Extension;ren $_.FullName $NewName}
}
啊是的,我也只编辑了BaseName,然后将扩展名附加到修改后的名称上进行重命名。
编辑: RegEx,这意味着什么...
好的,我不是在解释所有的RegEx,但我可以管理这一点。我们将从群组开始,其中有三个群组,它们用括号( )
表示。
目前,我们正在跳过第一组,然后转到第二组,这是我们真正想要的。第二组是[^.]+?
,我可以理解为什么这会让人感到困惑。因此方括号用于匹配一组字符。例如,[a-e]匹配a,b,c,d和e。简单的概念。克拉表示不,所以^。意味着除了一段时间之外它正在寻找任何东西。然后是+ ?,加号意味着重复前一个匹配(任何不是一个句点),而问号使它'非贪婪'意味着它将匹配所有它可以,但不超过它需要。所以它匹配第3组之前的所有非句号字符。
第3组是-.*
。第一个字符字面上匹配一个连字符,对于我们来说,它是在我们想要ToUpper()的字符分组之后,以及在FileName之前。然后它有.*
。在RegEx中,句点匹配除新行之外的任何字符(除了少数例外,如我们之前使用的范围组)。星号将重复前一个匹配零次或多次,因此它可以根据需要多次匹配任何字符。没有?在这之后,所以它是贪婪的并且将保持匹配直到它不能,并且由于句点匹配任何字符(大多数情况下),它消耗所有字符串的末尾。
回到第一组。 .+?\.
再次以句点开始,因此它匹配任何字符。 +表示它匹配1次或更多次,并且?意味着它尽可能地保持匹配,但不超过它所需要的。如果后跟一个转义期\.
,那么字面上匹配一个句号。基本上,这个小组会在第2组之前查找一段时间,并在该期间之前查找所有内容。
所以在纯文本中,它匹配:
anything, followed by a period, followed by any non-period characters up to a hyphen, and anything else after that hyphen
将它分成我们的小组:
(anything, at least one character, followed by a period), (followed by any non-period characters up to) (a hyphen, and anything else after that hyphen if there even is anything)
(.+?\.)([^.]+?)(-.*)
以下是RegEx101.com的链接,其中包含更易于理解的更直观的细分。 http://regex101.com/r/xF6zT2/1
答案 1 :(得分:1)
这应该为您打开一些选项。正则表达式肯定会在这里工作但不是必需的。您可以使用拆分来分解路径并根据需要将其重新组合在一起。
$folderpath = "C:\Temp\project"
Get-ChildItem -path $folderpath -Filter *.txt | ForEach-Object{
$parse = $_.Name.split(".-")
$parse[2].ToUpper()
# For the rename action you can uncomment the following
# Rename-Item -Path $_.FullName -NewName $($newname + $_.extension)
}
仅使用您包含的一个示例,我最终得到了一个名为J72E49Q2F7.txt
首先将-split
名称放入数组中。我们将分为.
和-
。不是字符序列。然后我们将位置2中的项目取出,这将是您要查找的字符串。 toUpper()
会将其设置为大写。如果您愿意,可以使用它来重命名文件。
注意:此解决方案取决于遵循此结构Project.Name.SOMETHINGRANDOM-FileName.txt
的文件,更重要的是它们以Project.Name.
开头。如果不是这种情况,正则表达式可能更合适,或者需要添加更多逻辑。