用一些字母替换非ASCII字符以保持文件格式相同

Posted

技术标签:

【中文标题】用一些字母替换非ASCII字符以保持文件格式相同【英文标题】:Replacing Non-Ascii characters with some Alphabets to maintain the file format same 【发布时间】:2014-01-07 20:59:51 【问题描述】:

这是我的代码:

byte[] bytes = File.ReadAllBytes(@"D:\project\wb_header.txt");
byte[] outp = bytes.Where(c => c >= 32 && c < 127).ToArray();
File.WriteAllBytes(@"D:\project\outputfile.txt", outp);

我在这里计算 wb_header.txt 文件中的所有非 Ascii 字符,并在删除非 ascii 字符后创建输出文件。但问题是我不想删除这些字符,我想用一些字母或 ASCII 字符替换它,以保持与 wb_header.txt 文件相同的文件格式。怎么做 ?请在此处包含一些代码

【问题讨论】:

您完全忽略了源文件的编码。由于多字节编码,这可能是有问题的。你实际上想做什么? 我实际上想在输出中用一些 ascii 值替换非 ascii 字符。 【参考方案1】:

您的代码仅在您的原始文件是 ASCII 时才有效,在这种情况下,如果您只想删除 non printable(我知道这样的旧定义)字符:

byte[] output = bytes
    .Select(c => (c >= 32 && c <= 127) ? c : (byte)63).ToArray();

这删除了所有不可打印的字符,将它们替换为 ?(问号,ASCII 代码 63)。

现在让我们看看为什么您的原始代码不适用于非 ASCII 文件。文本始终具有编码(ASCII、UTF-8、UTF-16 和许多其他)。前 127 个值在大多数编码中是相同的,因此您的代码可能会工作,但有些要编码的字符需要超过一个字节。例如,这个意大利语句子È sù 将像这样以 UTF-8 编码:

字节字符 195 136 È 32   115 195 185 ù

如您所见,有些字符需要超过一个字节。对于不同的编码,值当然是不同的。此外,一些文本文件有一个 BOM 标记来明确它们的编码(应该忽略它)。有一些技术可以转换,例如 e 中的 è (关于 SO 的一些非常好的文章)但不幸的是,您永远不能将非 ASCII 文本视为字节(我不甚至没有提到远东语言)。一个很好的近似可以是首先将文件作为文本读取(如果您不知道它的编码框架可以检查文件是否以 BOM 开头,这是一个严重的问题,因为除非您对文件内容有一些深入的了解,否则您不能猜猜看,也见this):

string content = File.ReadAllText("file.txt");

现在让我们用 ASCII 表示它(非 ASCII 字符会自动替换为 ?):

byte[] output = Encoding.ASCII.GetBytes(content);

此字节数组将包含不可打印的字符(超出 [32...127] 范围),那么您可能仍需要应用相同的过滤器:

byte[] output = Encoding.ASCII.GetBytes(content)
    .Select(c => (c >= 32 && c <= 127) ? c : (byte)63).ToArray();

最后说明:此代码根本没有效率。我们读取内存中的所有文件,我们转换为字节数组(在内存中)然后我们创建一个副本(再次在内存中)最终将其写回......对于大于几千字节的文件,您应该直接从文件中读取字符(一个接一个)使用正确的编码。啊...不要忘记 UNICODE 代理和修饰符...

【讨论】:

这给了我一个错误,比如不能将类型 system.collections.generic.IEnumerable 隐式转换为 byte[] @Debopam 我确实忘记了 ToArray(),我也更新了更多示例(关于为什么您的代码对于非 ASCII 输入文件会失败)。

以上是关于用一些字母替换非ASCII字符以保持文件格式相同的主要内容,如果未能解决你的问题,请参考以下文章

用 ascii 连字符“-”替换所有连字符类型

word中中文保持正体,英文用斜体的方法.

JS - 字符编码 (ASCII,Unicode,UTF-8)

求一个正则表达式: 以英文字母开头,只能包含英文字母、数字、下划线

Django:非ASCII字符

从 pandas 列中删除非 ASCII 字符