我正在将带有奇怪符号的字符串转换成Latin-1(或者至少是微软的做法),然后再转换回字符串。我使用PowerShell,但这只是关于.NET方法的:
$bytes = [System.Text.Encoding]::GetEncoding(1252).GetBytes($String)
$String = [System.Text.Encoding]::GetEncoding(1252).GetString($bytes)
这个方法很奇怪,只是奇怪的符号没有被删除,而是创建了问号,例如:
“你好?→”
变成
“你好????”
我想要的是只转换有效字节,而不创建问号,因此输出将是:
“喂?”
这可能吗?我已经搜索了一下,但是什么都没有找到。ChatGPT骗我说会有一个“GetValidBytes”方法,但是没有...
1条答案
按热度按时间3ks5zfa01#
一个选项是使用基于 *named Unicode块a的regex-based
-replace
操作:假设您的输入已经是一个.NET字符串(因此由UTF-16代码单元组成),那么就没有必要进行字节之间的转换:
\p{IsBasicLatin}
和\p{IsLatin-1Supplement
匹配ISO-8859-1 Unicode * 子范围 * 中的字符,该子范围 * 大部分 * 与Windows-1252相同,但缺少一些字符。€...
)是那些在ISO-8859-1中 * 不 * 存在的Windows-1252字符(因此在Unicode中与Windows-1252中具有不同的码位,即在8位范围之外)。–
和—
(短破折号和长破折号)放在 first,这样它们就不会被误认为描述了一个 range 字符(.NET regex引擎显然允许它们与-
互换使用,-
是常规的“破折号”(ASCII范围连字符)。‚
(单低9引号)是 * 双 * 的,以便 * 转义 * 它,因为PowerShell允许它与'
(单引号)互换使用-另请参阅:this answer总结了PowerShell中允许的所有此类可互换使用。通过将所有 * 非 * 匹配(
^
)字符替换为(隐含的)* 空字符串 *,所有非Windows-1252字符都将被有效地删除。一般警告:
然而,您的to-and-from-bytes编码方法 * 可以 * 稍加修改后使用,适用于 * 任何 * 目标编码(无需枚举单个字符,如上文所述):
使用以 empty string 初始化的
System.Text.EncoderReplacementFallback
示例可以有效地删除所有无法在目标编码中表示的字符。