在项目的实施过程中,类似化学分子式、平方、立方等,需要处理上、下标字符。
上下标字符的实现,大致有两种方式,一种是字符本身包含上下标信息,另一种方式是通过格式化标记实现上下标字符的显示。
Word中的上下标字符、HTML中的上下标字符,都是通过格式化标记实现的,即以m<SuperScript>2<SuperScript>此类方式存储,在显示的时候,根据标记显示上下标。此种方式灵活,可以将任意字符作为上下标,简单的可以理解为在四线格上写字,写在不同的位置上即可。
但该种方式存在一个问题,即格式的定义是一种契约,存储与显示必须遵循该契约,因此需要特定的编辑器和阅读器,简单的文本编辑器是不可以实现的。要使简单的文本编辑器可以实现上下标字符的编辑,则被编辑的字符本身需要带有上下标的信息,即需要将上下标信息进行字符编码。支持此类编码的字符集,Ascii自然是不行的,Unicode字符集对多数常用的上下标进行了编码实现。
使用Unicode编码实现上下标,需要相关的编辑器、阅读器、数据存储支持Unicode字符集,例如使用SqlServer存储过程处理信息时,可能存放上下标字符的变量应该定义为NVarchar而非Varchar。
以下辅助类实现Ascii字符到Unicode上、下标的转换,在实际应用中,可以通过定义一上、下标输入标记,然后对源字符串进行解析处理,实现字符串的上下标转换。例如,定义`为上标转义字符,^为下标转义字符,则H^2SO^4,m`3,通过识别对2、4进行下标处理,对3进行上标处理。
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace Eyuan.Common 6 { 7 /// <summary> 8 /// 上下标辅助类 9 /// </summary> 10 public static class SuperSubScriptHelper 11 { 12 /// <summary> 13 /// 转换为上标字符 14 /// </summary> 15 /// <param name="str"></param> 16 /// <returns></returns> 17 public static string ToSuperScriptStr(string str) 18 { 19 byte[] bytes = null; 20 bytes = SuperSubScriptHelper.ToSuperScript(str); 21 return Encoding.Unicode.GetString(bytes); 22 } 23 /// <summary> 24 /// 转换为上标 25 /// </summary> 26 /// <param name="str"></param> 27 /// <returns></returns> 28 public static byte[] ToSuperScript(string str) 29 { 30 byte[] bytes = new byte[2]; 31 switch (str) 32 { 33 case "0": 34 bytes[1] = Convert.ToByte(0x20); 35 bytes[0] = Convert.ToByte(0x70); 36 break; 37 case "1": 38 bytes[1] = Convert.ToByte(0x00); 39 bytes[0] = Convert.ToByte(0xB9); 40 break; 41 case "2": 42 bytes[1] = Convert.ToByte(0x00); 43 bytes[0] = Convert.ToByte(0xB2); 44 break; 45 case "3": 46 bytes[1] = Convert.ToByte(0x00); 47 bytes[0] = Convert.ToByte(0xB3); 48 break; 49 case "4": 50 bytes[1] = Convert.ToByte(0x20); 51 bytes[0] = Convert.ToByte(0x74); 52 break; 53 case "5": 54 bytes[1] = Convert.ToByte(0x20); 55 bytes[0] = Convert.ToByte(0x75); 56 break; 57 case "6": 58 bytes[1] = Convert.ToByte(0x20); 59 bytes[0] = Convert.ToByte(0x76); 60 break; 61 case "7": 62 bytes[1] = Convert.ToByte(0x20); 63 bytes[0] = Convert.ToByte(0x77); 64 break; 65 case "8": 66 bytes[1] = Convert.ToByte(0x20); 67 bytes[0] = Convert.ToByte(0x78); 68 break; 69 case "9": 70 bytes[1] = Convert.ToByte(0x20); 71 bytes[0] = Convert.ToByte(0x79); 72 break; 73 case "+": 74 bytes[1] = Convert.ToByte(0x20); 75 bytes[0] = Convert.ToByte(0x7A); 76 break; 77 case "-": 78 bytes[1] = Convert.ToByte(0x20); 79 bytes[0] = Convert.ToByte(0x7B); 80 break; 81 case "=": 82 bytes[1] = Convert.ToByte(0x20); 83 bytes[0] = Convert.ToByte(0x7C); 84 break; 85 case "(": 86 bytes[1] = Convert.ToByte(0x20); 87 bytes[0] = Convert.ToByte(0x7D); 88 break; 89 case ")": 90 bytes[1] = Convert.ToByte(0x20); 91 bytes[0] = Convert.ToByte(0x7E); 92 break; 93 case "n": 94 bytes[1] = Convert.ToByte(0x20); 95 bytes[0] = Convert.ToByte(0x7F); 96 break; 97 } 98 return bytes; 99 } 100 /// <summary> 101 /// 转换为下标字符 102 /// </summary> 103 /// <param name="str"></param> 104 /// <returns></returns> 105 public static string ToSubScriptStr(string str) 106 { 107 byte[] bytes =null; 108 bytes = SuperSubScriptHelper.ToSubScript(str); 109 return Encoding.Unicode.GetString(bytes); 110 } 111 /// <summary> 112 /// 转换为下标字节数组 113 /// </summary> 114 /// <param name="str"></param> 115 /// <returns></returns> 116 public static byte[] ToSubScript(string str) 117 { 118 byte[] bytes = new byte[2]; 119 switch (str) 120 { 121 case "0": 122 bytes[1] = Convert.ToByte(0x20); 123 bytes[0] = Convert.ToByte(0x80); 124 break; 125 case "1": 126 bytes[1] = Convert.ToByte(0x20); 127 bytes[0] = Convert.ToByte(0x81); 128 break; 129 case "2": 130 bytes[1] = Convert.ToByte(0x20); 131 bytes[0] = Convert.ToByte(0x82); 132 break; 133 case "3": 134 bytes[1] = Convert.ToByte(0x20); 135 bytes[0] = Convert.ToByte(0x83); 136 break; 137 case "4": 138 bytes[1] = Convert.ToByte(0x20); 139 bytes[0] = Convert.ToByte(0x84); 140 break; 141 case "5": 142 bytes[1] = Convert.ToByte(0x20); 143 bytes[0] = Convert.ToByte(0x85); 144 break; 145 case "6": 146 bytes[1] = Convert.ToByte(0x20); 147 bytes[0] = Convert.ToByte(0x86); 148 break; 149 case "7": 150 bytes[1] = Convert.ToByte(0x20); 151 bytes[0] = Convert.ToByte(0x87); 152 break; 153 case "8": 154 bytes[1] = Convert.ToByte(0x20); 155 bytes[0] = Convert.ToByte(0x88); 156 break; 157 case "9": 158 bytes[1] = Convert.ToByte(0x20); 159 bytes[0] = Convert.ToByte(0x89); 160 break; 161 case "+": 162 bytes[1] = Convert.ToByte(0x20); 163 bytes[0] = Convert.ToByte(0x8A); 164 break; 165 case "-": 166 bytes[1] = Convert.ToByte(0x20); 167 bytes[0] = Convert.ToByte(0x8B); 168 break; 169 case "=": 170 bytes[1] = Convert.ToByte(0x20); 171 bytes[0] = Convert.ToByte(0x8C); 172 break; 173 case "(": 174 bytes[1] = Convert.ToByte(0x20); 175 bytes[0] = Convert.ToByte(0x8D); 176 break; 177 case ")": 178 bytes[1] = Convert.ToByte(0x20); 179 bytes[0] = Convert.ToByte(0x8E); 180 break; 181 //case "n": 182 // bytes[1] = Convert.ToByte(0x20); 183 // bytes[0] = Convert.ToByte(0x8F); 184 // break; 185 } 186 return bytes; 187 } 188 } 189 }