如何在C#中替换扩展ASCII字符?

3

我试图替换一个非常大的字符串中的不可打印字符,即扩展ASCII字符。

foreach (string line in File.ReadLines(txtfileName.Text))
            {
                MessageBox.Show( Regex.Replace(line,
              @"\p{Cc}",
              a => string.Format("[{0:X2}]", " ")
            )); ;

            }

这似乎不能正常工作。

例如:AAÂAA 应转换为 AA AA。


你要用什么替换它们?替换成什么值?另外,编码格式是什么? - Sadique
@Sadiq AAÂAA 应该被转换为 AA AA。 - SamuraiJack
你必须说明你所指的“扩展ASCII”字符集,因为有几十个不同的字符集。而且,它们并没有涵盖Unicode中数千个字符。或者,你实际上想要替换除C0控制字符和基本拉丁字符之外的所有字符吗? - Tom Blodget
基于编程的相关内容从英语翻译成中文。仅返回翻译后的文本:仅使用基本拉丁字母。我不想要换行或制表符。空格可以。 - SamuraiJack
为什么你把“”作为“不可打印”的例子呢?将控制字符替换为相应的控制图片字符,就像在C0控制图表中所做的那样,这样怎么样? - Tom Blodget
2个回答

1
假设编码为 UTF8,请尝试以下操作:
string strReplacedVal = Encoding.ASCII.GetString(
        Encoding.Convert(
            Encoding.UTF8,
            Encoding.GetEncoding(
                Encoding.ASCII.EncodingName,
                new EncoderReplacementFallback(" "),
                new DecoderExceptionFallback()
                ),
            Encoding.UTF8.GetBytes(line)
        )
);

1
可以的。我会将其标记为答案。 顺便问一下,你能否告诉我如何逐行更新文本文件?这个文本文件非常大,我无法一次性读取它。 - SamuraiJack
你不觉得将所有文本都写入内存,而不是使用I/O密集型函数逐行替换文件中的文本会更有利于性能吗? - Sadique
文件可能超过300MB。我遇到了内存溢出异常。 - SamuraiJack
@Arbaaz,你已经做了(File.ReadLines())正在做的事情(逐行读取而不是一次性读取)- 不要被“ReadLines”这个名称所迷惑 ;) - Ian
@Arbaaz 如果你的数据很大(300MB),而且你需要它快速处理,那么你可能需要认真考虑性能问题,特别是如果你使用了像“Regex”这样的“过度杀伤”的方法。也许逐个字符检查+使用“unsafe”是最快的解决方案。 - Ian
显示剩余2条评论

0

既然你以UTF-8的格式打开文件,那么它必须是UTF-8格式。 因此,它的代码单位为一个字节,并且UTF-8具有编码字符的非常好的特性,即使用仅以上方向箭头(␡)上面的字节来编码超过该范围的字符,并使用仅在或以下方向箭头(␡)下面的字节来编码小于或等于该范围的字符。

为了提高效率,您可以每次以几KB为单位就地重写文件。

注意:某些字符可能会被替换为多个空格。

// Operates on a UTF-8 encoded text file
using (var stream = File.Open(path, FileMode.Open, FileAccess.ReadWrite))
{
    const int size = 4096;
    var buffer = new byte[size];
    int count; 
    while ((count = stream.Read(buffer, 0, size)) > 0)
    {
        var changed = false;
        for (int i = 0; i < count; i++)
        {
            // obliterate all bytes that are not encoded characters between ␠ and ␡ 
            if (buffer[i] < ' ' | buffer[i] > '\x7f')
            {
                buffer[i] = (byte)' ';
                changed = true;
            }
        }
        if (changed)
        {
            stream.Seek(-count, SeekOrigin.Current);
            stream.Write(buffer, 0, count);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接