在项目的实施过程中,类似化学分子式、平方、立方等,需要处理上、下标字符。
上下标字符的实现,大致有两种方式,一种是字符本身包含上下标信息,另一种方式是通过格式化标记实现上下标字符的显示。
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 }