今天遇到一个需求,需要我用delphi解析一个文档,用途类似于sqlldr,众所周知,sqlldr导入文件有几个关键要素,其中一个就是字段的分隔符,一般分隔符以不太常见的字符组合为佳,如 ^^|, ~|~之类的比较常见,但毕竟这些字符都是可以通过键盘敲入的,这就导致在极罕见的情况下,依然会有客户键盘敲入这些字符导致数据解析错误。
怎么解决这种情况呢,如果有一种字符窜,它是切实存在的,但是不能被键盘敲出来,不就行了吗,这就是传说中的 控制符。
这次我遇到的上游客户就很聪明,他们提供给我的文件使用java编写代码去跑的,生成文件时,将字段的分隔符定义成两个十六进制的01;即
byte[] b = { 0x01, 0x01 }; // 以两个0x01做分隔符
那么问题来了,于是文件到了我这里,我怎么去识别这个分隔符呢,这就要说到【控制符】了。
大家也许对ASCII码很熟悉,但是ASCII码的控制符是否了解呢,举个例子:
plsql:
select '第一行'||chr(13)||chr(10)||'第二行' from dual;
写过plsql的都知道这个运行的结果是啥样的,明明select了一行代码,怎么结果是两行呢?因为chr(13)和chr(10)是控制符,分别代表回车和换行的意思,这行sql里的chr(13)和chr(10)是不是似曾相识呢?我们再举个例子:
delphi:
procedure TForm1.btn1Click(Sender: TObject);
begin
showmessage('第一行'+#13#10 + '第二行');
end;
没错,这里的 #13和#10 也是控制符,分别代表回车和换行的意思,这代码里的#13和#10 是不是也似曾相识啊?
最终,我们去查看一下ASCII码表,下面这地址是我百度来的
到这里,我们终于揭开了控制符的神秘面纱,原来我们代码中的数字,就是对应着ascii码控制符的十进制数字,而这些ascii的意义就是不同的控制符。只不过plsql引用的方式是chr(ASCII),delphi的#ASCII,其他的工具语言欢迎各位大佬在评论里补充(帖子沉了就算了)。
那么回到今天我的需求,我要如何解析客户的文件?他们给的间隔符是两个十六进制的0x01,了解了控制符以后其实就会发现,其实两个十六进制的0x01,对应的ASCII十进制是1,表示标题开始(没什么实际意义)
所以我只要在代码中用chr(1)去解析就OK啦。