如何在尝试保存文件名之前删除非法字符?

MKA*_*NET 19 powershell powershell-2.0 powershell-3.0

我能够找到如何GetInvalidFileNameChars()在PowerShell脚本中使用该方法.但是,它似乎也过滤掉了空白(这是我不想要的).

编辑:也许我不是很清楚地问这个问题.我希望下面的函数包含文件名中已存在的空格.目前,脚本过滤掉空格.

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())), '')}
Run Code Online (Sandbox Code Playgroud)

Ans*_*ers 41

System.String实际上,将字符数组转换为使用空格连接数组元素,这意味着

[string][System.IO.Path]::GetInvalidFileNameChars()
Run Code Online (Sandbox Code Playgroud)

做同样的事

[System.IO.Path]::GetInvalidFileNameChars() -join ' '
Run Code Online (Sandbox Code Playgroud)

当你真正想要的时候

[System.IO.Path]::GetInvalidFileNameChars() -join ''
Run Code Online (Sandbox Code Playgroud)

正如@mjolinor所提到的(+1),这是由输出字段separator($OFS)引起的.

证据:

PS C:\> [RegEx]::Escape([string][IO.Path]::GetInvalidFileNameChars())
"\ \ \|\  \ ?\ ?\ ?\ ?\ ?\ ?\ \\ \t\ \n\ ?\ \f\ \r\ ?\ ?\ ?\ ?\ ?\ ?\ ¶\ §\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ :\ \*\ \?\ \\\ /
PS C:\> [RegEx]::Escape(([IO.Path]::GetInvalidFileNameChars() -join ' '))
"\ \ \|\  \ ?\ ?\ ?\ ?\ ?\ ?\ \\ \t\ \n\ ?\ \f\ \r\ ?\ ?\ ?\ ?\ ?\ ?\ ¶\ §\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ ?\ :\ \*\ \?\ \\\ /
PS C:\> [RegEx]::Escape(([IO.Path]::GetInvalidFileNameChars() -join ''))
"\| ????\t\n?\f\r??????¶§??????????:\*\?\\/
PS C:\> $OFS=''
PS C:\> [RegEx]::Escape([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)
}
Run Code Online (Sandbox Code Playgroud)

它应该做你想要的.

  • 下面的内容有点短,我认为不会牺牲可读性。将最后 2 行替换为 1:`return $Name -replace "[${invalidChars}]",'_'` (3认同)

hsi*_*mah 17

我目前最喜欢的方法是:

$Path.Split([IO.Path]::GetInvalidFileNameChars()) -join '_'
Run Code Online (Sandbox Code Playgroud)

_与以下替代方案相比,这将所有无效字符替换为并且非常易读:

$Path -replace "[$([RegEx]::Escape([string][IO.Path]::GetInvalidFileNameChars()))]+","_"
Run Code Online (Sandbox Code Playgroud)


mjo*_*nor 6

我怀疑它与非显示字符被强制为[string]进行正则表达式操作(最后表示为空格)有关.

看看这是否更好:

([char[]]$name | where { [IO.Path]::GetinvalidFileNameChars() -notcontains $_ }) -join ''
Run Code Online (Sandbox Code Playgroud)

这将进行直接的字符比较,并且似乎更可靠(嵌入空间不会被删除).

$name = 'abc*\ def.txt'
([char[]]$name | where { [IO.Path]::GetinvalidFileNameChars() -notcontains $_ }) -join ''

abc def.txt
Run Code Online (Sandbox Code Playgroud)

编辑 - 我相信@Ansgar对于将字符数组转换为字符串所造成的空间是正确的.这个空间由$ OFS引入.


小智 6

我想要空格替换所有非法字符,所以空格替换为空格

$Filename = $ADUser.SamAccountName
[IO.Path]::GetinvalidFileNameChars() | ForEach-Object {$Filename = $Filename.Replace($_," ")}
$Filename = "folder\" + $Filename.trim() + ".txt"
Run Code Online (Sandbox Code Playgroud)