PowerShell无法识别目录名中的弯引号,替换直引号失败求助
解决PowerShell无法识别目录名中弯引号的问题
问题背景
需要将读取到的目录名字符串中的弯引号(’、“、”)替换为直引号('、"),仅用于后续字符串处理,无需重命名目录。测试用目录结构:
D:\Test Double Left “ Quote Double Right ” Quote Single ’ Quote
测试代码:
$count = 0 Get-ChildItem -LiteralPath 'D:\test' -Directory | ForEach-Object { $name = $_.Name Write-Host $name if ($name.Contains("’")) { Write-Host "Single Curly Quote: $name" $name = $name -replace("’","'") Write-Host "Fixed: $name" } if ($name.Contains('“')) { Write-Host "Double Left Curly Quote: $name" $name = $name -replace('“','"') Write-Host "Fixed: $name" } if ($name.Contains('”')) { Write-Host "Double Right Curly Quote: $name" $name = $name -replace('”','"') Write-Host "Fixed: $name" } $count += 1 } Write-Host $count
运行结果:
C:\Users\brian.w.williams> . 'C:\Users\brian.w.williams\Desktop\Test.ps1' Double Left “ Quote Double Right ” Quote Single ’ Quote 3
代码无法识别目录名中的弯引号,但手动创建的字符串变量可正常替换,环境为PowerShell 7 + Windows 10 x64。
解决方法
1. 使用Unicode编码精准匹配字符
Windows文件系统中的弯引号可能存在Unicode编码变体,直接写字符可能出现匹配失败。改用Unicode转义序列指定目标字符,匹配更可靠:
$count = 0 Get-ChildItem -LiteralPath 'D:\test' -Directory | ForEach-Object { $name = $_.Name Write-Host $name # 匹配单弯引号(U+2019) if ($name -match [regex]::Escape([char]0x2019)) { Write-Host "Single Curly Quote: $name" $name = $name -replace [regex]::Escape([char]0x2019), "'" Write-Host "Fixed: $name" } # 匹配左双弯引号(U+201C) if ($name -match [regex]::Escape([char]0x201C)) { Write-Host "Double Left Curly Quote: $name" $name = $name -replace [regex]::Escape([char]0x201C), '"' Write-Host "Fixed: $name" } # 匹配右双弯引号(U+201D) if ($name -match [regex]::Escape([char]0x201D)) { Write-Host "Double Right Curly Quote: $name" $name = $name -replace [regex]::Escape([char]0x201D), '"' Write-Host "Fixed: $name" } $count += 1 } Write-Host $count
2. 简化批量替换逻辑
可以通过映射表一次性替换所有目标弯引号,减少冗余判断:
$count = 0 # 定义弯引号与直引号的映射关系 $quoteMap = @{ [char]0x2019 = "'" # 单弯引号 [char]0x201C = '"' # 左双弯引号 [char]0x201D = '"' # 右双弯引号 } Get-ChildItem -LiteralPath 'D:\test' -Directory | ForEach-Object { $name = $_.Name Write-Host "Original: $name" # 遍历映射表完成替换 foreach ($char in $quoteMap.Keys) { $name = $name -replace [regex]::Escape($char), $quoteMap[$char] } Write-Host "Fixed: $name`n" $count += 1 } Write-Host "Total processed: $count"
3. 验证字符实际编码
如果以上方法仍无效,可先输出目录名中每个字符的Unicode编码,确认目标字符的真实编码值:
Get-ChildItem -LiteralPath 'D:\test' -Directory | ForEach-Object { Write-Host "`nChecking: $($_.Name)" $_.Name.ToCharArray() | ForEach-Object { Write-Host "Character: '$_' | Unicode: U+$([int]$_).ToString('X4')" } }
根据输出的编码值,替换代码中对应的Unicode转义序列即可。
内容的提问来源于stack exchange,提问作者BW_Wyo
相关产品推荐
相关产品推荐

