Mapping 有没有办法将文本从Unicode压缩到ASCII?

Mapping 有没有办法将文本从Unicode压缩到ASCII?,mapping,ascii,special-characters,varchar,unicode-normalization,Mapping,Ascii,Special Characters,Varchar,Unicode Normalization,我需要的是,对于每个ASCII字符,一个等效Unicode字符的列表 问题是,当人们在文档中键入内容时,Microsoft Excel和Word等程序会插入非ASCII双引号、单引号、破折号等。我想将此文本存储在“varchar”类型的数据库字段中,该字段需要单字节字符 为了存储ASCII(单字节)文本,其中一些Unicode字符可以被视为与特定ASCII字符等效或足够相似,用等效ASCII字符替换Unicode字符就可以了 我想要一个简单的函数,比如MapToASCII,它可以将Unicode

我需要的是,对于每个ASCII字符,一个等效Unicode字符的列表

问题是,当人们在文档中键入内容时,Microsoft Excel和Word等程序会插入非ASCII双引号、单引号、破折号等。我想将此文本存储在“varchar”类型的数据库字段中,该字段需要单字节字符

为了存储ASCII(单字节)文本,其中一些Unicode字符可以被视为与特定ASCII字符等效或足够相似,用等效ASCII字符替换Unicode字符就可以了

我想要一个简单的函数,比如MapToASCII,它可以将Unicode文本转换为ASCII等价物,允许我为任何与ASCII字符不相似的Unicode字符指定替换字符。

Win32 API可以用于此转换(Unicode到ANSI)。使用CP_ACP作为第一个参数。这样做可能比尝试构建自己的映射函数要好

编辑冒着听起来像是我在试图将其作为违背OP意愿的解决方案来推广的风险,似乎值得指出的是,该API在很大程度上(全部?)满足了OP的要求。目标是(我认为)尽可能地将Unicode字符串映射到“ANSI”(在本例中,ANSI可能是一个移动目标)。另外一个要求是能够为那些无法映射的字符指定一些替代字符。下面的示例就是这样做的。它将Unicode字符串“转换”为
char
,并对无法转换的字符使用下划线(倒数第二个参数)

ret = WideCharToMultiByte( CP_ACP, 0, L"abc個חあЖdef", -1, 
                           ac, sizeof( ac ), "_", NULL );
for ( i = 0; i < strlen( ac ); i++ )
  printf( "%c %02x\n", ac[i], ac[i] );
ret=WideCharToMultiByte(CP_ACP,0,L“abc個חあЖdef“,-1,
ac,sizeof(ac),“_u2;”,NULL);
对于(i=0;i
Win32 API可用于此转换(Unicode到ANSI)。使用CP_ACP作为第一个参数。这样做可能比尝试构建自己的映射函数要好

编辑冒着听起来像是我在试图将其作为违背OP意愿的解决方案来推广的风险,似乎值得指出的是,该API在很大程度上(全部?)满足了OP的要求。目标是(我认为)尽可能地将Unicode字符串映射到“ANSI”(在本例中,ANSI可能是一个移动目标)。另外一个要求是能够为那些无法映射的字符指定一些替代字符。下面的示例就是这样做的。它将Unicode字符串“转换”为
char
,并对无法转换的字符使用下划线(倒数第二个参数)

ret = WideCharToMultiByte( CP_ACP, 0, L"abc個חあЖdef", -1, 
                           ac, sizeof( ac ), "_", NULL );
for ( i = 0; i < strlen( ac ); i++ )
  printf( "%c %02x\n", ac[i], ac[i] );
ret=WideCharToMultiByte(CP_ACP,0,L“abc個חあЖdef“,-1,
ac,sizeof(ac),“_u2;”,NULL);
对于(i=0;i
这里有一个非常相关的问题:

虽然答案不充分,但它给了我一个想法。我可以将基本多语言平面(0)中的每个Unicode代码点映射到一个等效的ASCII字符(如果存在的话)。下面的C#代码将有助于创建一个HTML表单,您可以在其中为每个值键入替换字符

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.IO;

namespace UnicodeCharacterCategorizer
{
    class Program
    {
        static void Main(string[] args)
        {
            string output_filename = "output.htm"; //set a filename if not specifying one through the command line
            Dictionary<UnicodeCategory,List<char>> category_character_sets = new Dictionary<UnicodeCategory,List<char>>();
            foreach (UnicodeCategory c in Enum.GetValues(typeof(UnicodeCategory)))
                category_character_sets.Add( c, new List<char>() );
            for (int i = 0; i <= 0xFFFF; i++)
            {
                if (i >= 0xD800 && i <= 0xDFFF) continue; //Skip ranges reserved for high/low surrogate pairs.
                char c = (char)i;
                UnicodeCategory category = char.GetUnicodeCategory( c );
                category_character_sets[category].Add( c );
            }
            StringBuilder file_data = new StringBuilder( @"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd""><html xmlns=""http://www.w3.org/1999/xhtml""><head><title>Unicode Category Character Sets</title><style>.categoryblock{border:3px solid black;margin-bottom:10px;padding:5px;} .characterblock{display:inline-block;border:1px solid grey;padding:5px;margin-right:5px;} .character{display:inline-block;font-weight:bold;background-color:#ffeeee} .numericvalue{color:blue;}</style></head><body><form id=""charactermap"">" );
            foreach (KeyValuePair<UnicodeCategory,List<char>> entry in category_character_sets)
            {
                file_data.Append( @"<div class=""categoryblock""><h1>" + entry.Key.ToString() + ":</h1><br />" );
                foreach (char c in entry.Value)
                {
                    string hex_value = ((int)c).ToString( "x" );
                    file_data.Append( @"<div class=""characterblock""><span class=""character"">&#x" + hex_value + @";<br /><span class=""numericvalue"">" + hex_value + @"</span><br /><input type=""text"" name=""r_" + hex_value + @""" /></div>" );
                }
                file_data.Append( "</div>" );
            }
            file_data.Append("</form></body></html>" );
            File.WriteAllText( output_filename, file_data.ToString(), Encoding.Unicode );
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
利用制度全球化;
使用System.IO;
命名空间字符分类程序
{
班级计划
{
静态void Main(字符串[]参数)
{
string output_filename=“output.htm”;//如果未通过命令行指定文件名,请设置文件名
字典类别\字符\集合=新字典();
foreach(Enum.GetValues中的Unicode分类c(typeof(Unicode分类)))
类别字符集。添加(c,新列表());

对于(int i=0;i=0xD800&&i一个高度相关的问题如下:

虽然答案不充分,但它给了我一个想法。我可以将基本多语言平面(0)中的每个Unicode代码点映射到一个等效的ASCII字符(如果存在)。下面的C#代码将有助于创建一个HTML表单,您可以在其中为每个值键入替换字符

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.IO;

namespace UnicodeCharacterCategorizer
{
    class Program
    {
        static void Main(string[] args)
        {
            string output_filename = "output.htm"; //set a filename if not specifying one through the command line
            Dictionary<UnicodeCategory,List<char>> category_character_sets = new Dictionary<UnicodeCategory,List<char>>();
            foreach (UnicodeCategory c in Enum.GetValues(typeof(UnicodeCategory)))
                category_character_sets.Add( c, new List<char>() );
            for (int i = 0; i <= 0xFFFF; i++)
            {
                if (i >= 0xD800 && i <= 0xDFFF) continue; //Skip ranges reserved for high/low surrogate pairs.
                char c = (char)i;
                UnicodeCategory category = char.GetUnicodeCategory( c );
                category_character_sets[category].Add( c );
            }
            StringBuilder file_data = new StringBuilder( @"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd""><html xmlns=""http://www.w3.org/1999/xhtml""><head><title>Unicode Category Character Sets</title><style>.categoryblock{border:3px solid black;margin-bottom:10px;padding:5px;} .characterblock{display:inline-block;border:1px solid grey;padding:5px;margin-right:5px;} .character{display:inline-block;font-weight:bold;background-color:#ffeeee} .numericvalue{color:blue;}</style></head><body><form id=""charactermap"">" );
            foreach (KeyValuePair<UnicodeCategory,List<char>> entry in category_character_sets)
            {
                file_data.Append( @"<div class=""categoryblock""><h1>" + entry.Key.ToString() + ":</h1><br />" );
                foreach (char c in entry.Value)
                {
                    string hex_value = ((int)c).ToString( "x" );
                    file_data.Append( @"<div class=""characterblock""><span class=""character"">&#x" + hex_value + @";<br /><span class=""numericvalue"">" + hex_value + @"</span><br /><input type=""text"" name=""r_" + hex_value + @""" /></div>" );
                }
                file_data.Append( "</div>" );
            }
            file_data.Append("</form></body></html>" );
            File.WriteAllText( output_filename, file_data.ToString(), Encoding.Unicode );
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
利用制度全球化;
使用System.IO;
命名空间字符分类程序
{
班级计划
{
静态void Main(字符串[]参数)
{
string output_filename=“output.htm”;//如果未通过命令行指定文件名,请设置文件名
字典类别\字符\集合=新字典();
foreach(Enum.GetValues中的Unicode分类c(typeof(Unicode分类)))
类别字符集。添加(c,新列表());

对于(inti=0;i=0xD800&&i)来说,射中自己的脚看起来很有趣:"
CP\u ACP
:系统默认的Windows ANSI代码页。注意:此值在不同的计算机上可能不同,即使在同一网络上也是如此。它可以在同一台计算机上更改,导致存储的数据变得不可恢复地损坏。此值仅用于临时使用,如果可能,永久存储应使用UTF-16或UTF-8“但是,看起来OP喜欢互相不兼容的字符集带来的痛苦,而你的回答正确地让他这么做了,所以我给他+1。@Piskvor:的确!使用这个函数的结果只有5%的时间是令人满意的(满意是一个相对的术语;)但是,如果不了解OP的要求,很难说;它实际上可以正常工作。这根本不是一个解决方案。我正在尝试将Unicode字符映射到其ASCII等效字符(如果存在)。任何与ASCII字符不同的Unicode字符都将