首页 > 解决方案 > 使用 Powershell 删除 unicode 字符

问题描述

我在 Excel 中使用 vlookup 时遇到一些问题。我已经看到了这个问题,但我没有得到解决方案是的。

我在 txt 文件中有大量行,这些行包含 Unicode 字符。

示例:这一行:“S0841488.JPG06082014‏‎08.21”包含这两个 Unicode 字符:U+200F U+200E 'S0841488.JPG06082014 U+200F U+200E 08.21。

请告诉我如何使用 Powershell 删除这些 un​​icode 字符。

标签: powershellunicode

解决方案


如果要删除所有超出 ASCII 范围(Unicode 代码点范围U+0000- U+007F)的字符:

PowerShell (Core) 7+解决方案:

# Removes any non-ASCII characters from the LHS string,
# which includes the problematic hidden control characters.
'S0841488.JPG06082014‏‎08.21' -replace '\P{IsBasicLatin}'

该解决方案使用基于正则表达式的-replace运算符,带有 Unicode块名称的否定形式 ( \P) ,它指的是 Unicode 的 ASCII 子范围。简而言之:匹配任何非 ASCII 字符,并且由于没有指定替换字符串,因此有效地将其删除;结合总是替换输入字符串中的所有匹配项,所有非 ASCII 字符都将被删除。 IsBasicLatin\P{IsBasicLatin}-replace

Windows PowerShell解决方案:

令人难以置信的是,Windows PowerShell 中的一个错误(从 v5.1.19041.1023 开始;v5.1.x 是最新和最终版本)源自底层 .NET Framework 4.8.4390.0,错误认为 ASCII 范围i/超出ASCII 范围I,因此将其删除;解决方法

# WORKAROUND for Windows PowerShell to prevent removal of 'I' / 'i'
'Ii-S0841488.JPG06082014‏‎08.21' -replace '[^i\p{IsBasicLatin}]'

您可以在函数的帮助下验证这是否有效地从字符串中删除了(不可见的)LEFT-TO-RIGHT MARKU+200E和 RIGHT-TO-LEFT MARKU+200F字符,该Debug-String函数可作为MIT 许可的 Gist 获得

# Download and define the Debug-String function.
# NOTE: 
#  I can personally assure you that doing this is safe, but you
#  you should always check the source code first.
irm https://gist.github.com/mklement0/7f2f1e13ac9c2afaf0a0906d08b392d1/raw/Debug-String.ps1 | iex


# Visualize the existing non-ASCII-range characters
'S0841488.JPG06082014‏‎08.21' | Debug-String -UnicodeEscapes

# Remove them and verify that they're gone.
'S0841488.JPG06082014‏‎08.21' -replace '\P{IsBasicLatin}' | Debug-String -UnicodeEscapes

以上产生以下结果:

S0841488.JPG06082014`u{200f}`u{200e}08.21
S0841488.JPG0608201408.21

注意不可见控制字符在原始输入字符串中的可视化,`u{200f}以及在应用操作`u{200e}后它们如何不再存在。-replace

在 PowerShell (Core) 7+(但不是 Windows PowerShell)中,此类 Unicode 转义序列也可用于可扩展字符串,即在双引号字符串文字中(例如,"Hi`u{21}"扩展为逐字Hi!) - 请参阅概念about_Special_Characters帮助主题。


推荐阅读