代码之家  ›  专栏  ›  技术社区  ›  Justin C

在ASCII和.NET字符之间手动转换

  •  6
  • Justin C  · 技术社区  · 16 年前

    我正在写一些代码来清除我的ASP.NET站点的用户输入。我需要清除输入以删除对ASCII字符145、146、147、148的所有引用,这些字符偶尔会从我的Mac用户那里得到输入,这些用户正在复制和粘贴他们在Mac上的字处理器中写入的内容。

    我的问题是以下三个字符串,我相信应该输出相同的文本。

    string test1 = Convert.ToChar(147).ToString();
    string test2 = String.Format("'{0}'", Convert.ToChar(147));
    
    char[] characters = System.Text.Encoding.ASCII.GetChars(new byte[] { 147 });
    string test3 = new string(characters);
    

    但是,当我将ASP文本框设置为等于以下值时

    txtShowValues.Text = test1 + "*" + test2 + "*" + test3;
    

    我为test1得到一个空值,test2工作正常,test3输出为'?'.

    有人能解释发生了什么不同吗?我希望这能帮助我理解.NET是如何使用超过128个字符的ASCII值的,这样我就可以编写一个好的清理脚本。

    编辑
    我提到的值(145-148)是花引号。所以单左,单右,双左,双右。

    我所说的“工作正常”,是指它向我的浏览器输出一个卷曲的引号。

    二次编辑
    下面的代码(在答案中提到)也输出大引号。所以问题可能是在测试3中使用了ASCII。

    char[] characters2 = System.Text.Encoding.Default.GetChars(new byte[] { 147 });
    string test4 = new string(characters2);
    

    第三编辑
    我找到了一台可以借用的Mac电脑,可以复制这个问题。当我从Word中复制并粘贴带有引号的文本到Mac上的Web应用程序时,它会粘贴卷曲的引号(147和148)。当我点击save curly quotes时,它会被保存到数据库中,所以我将使用您帮助我清除这些内容的代码。

    第4次编辑
    花了一些时间根据这里的响应编写更多的示例代码,并注意到它与ASP.NET中的多行文本框有关。这里有很好的信息,所以我决定开始一个新问题: ASP.NET Multiline textbox allowing input above UTF-8

    3 回复  |  直到 16 年前
        1
  •  11
  •   bobince    16 年前

    字符147是U+0093设置发送状态。与0-255范围内的所有Unicode字符一样,它与相同数字的ISO-8859-1字符相同。ISO-8859-1将147分配给这个不可见的控制代码。

    您所想的不是__ascii__甚至是__iso-8859-1_,而是Windows代码页1252。这是一种非标准编码,即 喜欢 8859-1,但将字符128-159分配给各种排版扩展,如智能引号,而不是基本上无用的控制代码。在代码页1252中,字符147是 “ ,aka U+201C左双引号。

    如果要将Windows代码页(通常错误地称为__ansi_)转换为Unicode字符,则需要指定所需的代码页,例如:

    System.Text.Encoding.getEncoding(1252).GetChars(new byte[] { 147 })
    

    System.Text.Encoding.Default 将为您提供服务器上的默认编码。对于西欧地区的服务器,这将是1252。在其他地方,不会。通常,在服务器应用程序中依赖于区域设置的默认代码页不是一个好主意。

    无论如何,你应该 像147这样的字节代表 艾斯 在Web应用程序的输入中。只有当您的页面本身使用代码页1252编码时才会发生这种情况(并且只是为了混淆和误导更多内容,当您说您的页面是ISO-8859-1格式时,浏览器会悄悄地使用代码页1252)。如果您没有为您的页面指定任何编码,那么您的页面也可能位于1252(浏览器会猜测;其他区域设置会猜测不同的代码页,因此这将是一个大混乱)。

    确保对Web应用中的所有编码都使用UTF-8,并且 mark your pages as such .今天,所有的Web应用程序都应该使用UTF-8。

        2
  •  3
  •   John Knoeller    16 年前

    .NET使用的Unicode(UCS-2)与ASCII相同,仅用于128以下的值。

    ASCII没有定义高于127的值。

    我认为您可能会想到ANSI,它将127以上的值定义为(大部分)大多数欧洲语言所需的语言字符。或OEM(原始的IBM PC字符集),它将字符>127定义为(大部分)符号。

    127以上字符的解释方式的差异称为代码页或编码。(因此,System.Text.Encoding)。因此,如果使用不同的编码,您可能会使测试3正常工作,也许 System.Text.Encoding.Default .

    编辑:好吧,既然我们知道了您想要的编码是ANSI,那么现在发生的事情就更清楚了。

    字符转换的规则是替换在编码中不能表示为其他字符(通常是一个方框)的字符。但是对于ASCII,没有方框字符,所以它使用?相反。这就解释了测试3。

    测试1和2都使用了带整数常量的convert.tochar。它将把输入解释为Unicode字符,而不是ANSI字符,因此不应用转换。Unicode字符147是非打印字符。

        3
  •  0
  •   technophile    16 年前

    我在一个控制台应用程序(.net 3.5sp1)中得到了所有3个问号。据我所知,它们都应该是等效的。约翰·诺勒关于ASCII和ANSI是正确的。

    您是否尝试在原始字符串上使用一个编码类“getBytes()并迭代,删除(通过将“好”字节复制到另一个缓冲区)您不想要的值?

    例如(使用LINQ):

    byte[] original = System.Text.Encoding.ASCII.GetBytes(badString);
    byte[] clean = (from b in original where b < 145 || b > 148 select b).ToArray<byte>();
    string cleanString = System.Text.Encoding.ASCII.GetString(clean);
    

    老实说,在这里使用ASCII可能是错误的;如果原始文本是Unicode,它可能会做一些不好的事情(例如,如果您通过了UTF-16)。

    推荐文章