我能够找到如何在PowerShell脚本中使用GetInvalidFileNameChars()
方法。然而,它似乎也过滤掉了空白(这是我不想要的)。
编辑:也许我问得不够清楚。我希望下面的函数包含文件名中已经存在的空格。目前,脚本会过滤掉空间。
Function Remove-InvalidFileNameChars {
param([Parameter(Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[String]$Name
)
return [RegEx]::Replace($Name, "[{0}]" -f ([RegEx]::Escape([String][System.IO.Path]::GetInvalidFileNameChars())), '')}
将字符数组转换为System.String
实际上似乎是用空格连接数组元素,这意味着
[string][System.IO.Path]::GetInvalidFileNameChars()
和一样
[System.IO.Path]::GetInvalidFileNameChars() -join ' '
当你真正想要时
[System.IO.Path]::GetInvalidFileNameChars() -join ''
正如@mjolinor提到的(+1),这是由输出字段分隔符($OFS
)引起的。
证据:
PS C:\>[RegEx]::转义([string][IO.Path]::GetInvalidFileNameChars())"☺\☻\♥\ ♦\ ♣\ ♠\ \\ \t\\n\♂\ \f\\r\♫\ ☼\ ►\ ◄\↕\ ‼\¶\§\▬\ ↨\ ↑\ ↓\ →\ ←\ ∟\↔\▲\ ▼\ :\ \*\ \?\ \\\/PS C:\>[RegEx]::转义(([IO.Path]::GetInvalidFileNameChars()-加入")"☺\☻\♥\ ♦\ ♣\ ♠\ \\ \t\\n\♂\ \f\\r\♫\ ☼\ ►\ ◄\↕\ ‼\¶\§\▬\ ↨\ ↑\ ↓\ →\ ←\ ∟\↔\▲\ ▼\ :\ \*\ \?\ \\\/PS C:\>[RegEx]::转义(([IO.Path]::GetInvalidFileNameChars()-加入")"☺☻♥♦\t\n♂\f\r♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼:\*\?\\/PS C:\>$OFS=''PS C:\>[RegEx]::转义([string][IO.Path]::GetInvalidFileNameChars())"☺☻♥♦\t\n♂\f\r♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼:\*\?\\/
将您的功能更改为以下内容:
Function Remove-InvalidFileNameChars {
param(
[Parameter(Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[String]$Name
)
$invalidChars = [IO.Path]::GetInvalidFileNameChars() -join ''
$re = "[{0}]" -f [RegEx]::Escape($invalidChars)
return ($Name -replace $re)
}
它应该做你想做的事。
我目前最喜欢的方法是:
$Path.Split([IO.Path]::GetInvalidFileNameChars()) -join '_'
这将用_
替换所有无效字符,与等替代方案相比,它非常便于人类阅读
$Path -replace "[$([RegEx]::Escape([string][IO.Path]::GetInvalidFileNameChars()))]+","_"
我怀疑这与regex操作中非显示字符被强制为[string]有关(最终用空格表示)。
看看这是否效果更好:
([char[]]$name | where { [IO.Path]::GetinvalidFileNameChars() -notcontains $_ }) -join ''
这将进行直接的字符比较,而且似乎更可靠(嵌入的空格没有被删除)。
$name = 'abc* def.txt'
([char[]]$name | where { [IO.Path]::GetinvalidFileNameChars() -notcontains $_ }) -join ''
abc def.txt
编辑-我相信@Ansgar关于将字符数组强制转换为字符串所导致的空格是正确的。该空间由$OFS引入。
我想要空格来替换所有非法字符,所以空格被替换为空格
$Filename = $ADUser.SamAccountName
[IO.Path]::GetinvalidFileNameChars() | ForEach-Object {$Filename = $Filename.Replace($_," ")}
$Filename = "folder" + $Filename.trim() + ".txt"
请尝试使用相同底层函数的这一行。
以匹配
'?Some "" File Name <:.txt' -match ("[{0}]"-f (([System.IO.Path]::GetInvalidFileNameChars()|%{[regex]::Escape($_)}) -join '|'))
取代
'?Some "" File Name <:.txt' -replace ("[{0}]"-f (([System.IO.Path]::GetInvalidFileNameChars()|%{[regex]::Escape($_)}) -join '|')),'_'
[System.IO.Path]::GetInvalidFileNameChars()
返回一个无效字符数组。如果它为您返回空格字符(我没有这样做),您可以始终迭代数组并将其删除。
> $chars = @()
> foreach ($c in [System.IO.Path]::GetInvalidFileNameChars())
{
if ($c -ne ' ')
{
$chars += $c
}
}
然后可以使用$chars
,就像使用GetInvalidFileNameChars()
的输出一样。
非常不同的、组合的、灵活的方法。我发现GetInvalidFileNameChars()并没有获得所有符合我需要的非法字符。
$arrInvalidChars = '[]/|+={}-$%^&*()'.ToCharArray()
$cleanName = 'a[]|+={9}-$%^&*()b'
$arrInvalidChars | % { $cleanName = $cleanName.replace($_,'_')}
返回$cleanName='a_______ 9__________ b'