您的位置:首页 > 编程语言 > VB

用VBS判断无BOM头的文件是否UTF-8编码

2014-11-15 22:39 721 查看
http://demon.tw/programming/vbs-validate-utf8.html

标签:BOM,
UTF-8,VB,
VBS,VBScript

标题:用VBS判断无BOM头的文件是否UTF-8编码

作者:Demon

链接:http://demon.tw/programming/vbs-validate-utf8.html
版权:本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享2.5中国大陆”协议条款。

在VBS贴吧看到吧主发的一个《如何区别无BOM头的UTF-8和GBK?》的贴子,故为此文。这种问题都解决不了,VBS吧主的水平也不过如此。

字节顺序记号(英语:byte-ordermark,BOM)是位于码点U+FEFF的统一码字符的名称。当以UTF-16或UTF-32来将UCS/统一码字符所组成的字符串编码时,这个字符被用来标示其字节序。它常被用来当做标示文件是以UTF-8、UTF-16或UTF-32编码的记号。

更多关于BOM的资料请自己阅读维基百科。

批处理之家有个《VBS版文件编码识别、转换工具(GB2312、UTF-8、Unicode、BIG5)》的帖子,其中检测文件编码的CheckCode.vbs是这么写的:

FunctionCheckCode(Usage)
Dimslz
setslz=CreateObject("Adodb.Stream")
slz.Type=1
slz.Mode=3
slz.Open
slz.Position=0
slz.Loadfromfilefile
Bin=slz.read(2)
ifAscB(MidB(Bin,1,1))=&HEFandAscB(MidB(Bin,2,1))=&HBBThen
Codes="UTF-8"
elseifAscB(MidB(Bin,1,1))=&HFFandAscB(MidB(Bin,2,1))=&HFEThen
Codes="Unicode"
else
Codes="GB2312"
endif
WScript.echofile,Usage,Codes
slz.Close
setslz=Nothing
EndFunction


这个代码只检测了BOM,把没有BOM的文件都认为是GB2312编码,很显然是错误的。并不是所有UTF-8编码的文件都带BOM标记的,事实上,绝大部分UTF-8文件都不带BOM。

理论上,要准确地判断一个文件的编码是很困难的,但是判断一个文件是否为UTF-8编码却相对比较简单,在《构建可扩展的Web站点》一书中就有很好的PHP代码:

<?php
functionis_valid_utf8(&$input){
$rx='[\xC0-\xDF]([^\x80-\xBF]|$)';
$rx.='|[\xE0-\xEF].{0,1}([^\x80-\xBF]|$)';
$rx.='|[\xF0-\xF7].{0,2}([^\x80-\xBF]|$)';
$rx.='|[\xF8-\xFB].{0,3}([^\x80-\xBF]|$)';
$rx.='|[\xFC-\xFD].{0,4}([^\x80-\xBF]|$)';
$rx.='|[\xFE-\xFE].{0,5}([^\x80-\xBF]|$)';
$rx.='|[\x00-\x7F][\x80-\xBF]';
$rx.='|[\xC0-\xDF].[\x80-\xBF]';
$rx.='|[\xE0-\xEF]..[\x80-\xBF]';
$rx.='|[\xF0-\xF7]...[\x80-\xBF]';
$rx.='|[\xF8-\xFB]....[\x80-\xBF]';
$rx.='|[\xFC-\xFD].....[\x80-\xBF]';
$rx.='|[\xFE-\xFE]......[\x80-\xBF]';
$rx.='|^[\x80-\xBF]';
returnpreg_match("!$rx!",$input)?0:1;
}
?>


我们要做的就是改写成VBS:

Functionread(path)
'将Byte()数组转成String字符串
Dimado,a(),i,n
Setado=CreateObject("ADODB.Stream")
ado.Type=1:ado.Open
ado.LoadFromFilepath
n=ado.Size-1
ReDima(n)
Fori=0Ton
a(i)=ChrW(AscB(ado.Read(1)))
Next
read=Join(a,"")
EndFunction

'Author:Demon
'Date:2011/11/10
'Website:http://demon.tw
Functionis_valid_utf8(ByRefinput)'ByRef以提高效率
Dims,re
Setre=NewRegexp
s="[\xC0-\xDF]([^\x80-\xBF]|$)"
s=s&"|[\xE0-\xEF].{0,1}([^\x80-\xBF]|$)"
s=s&"|[\xF0-\xF7].{0,2}([^\x80-\xBF]|$)"
s=s&"|[\xF8-\xFB].{0,3}([^\x80-\xBF]|$)"
s=s&"|[\xFC-\xFD].{0,4}([^\x80-\xBF]|$)"
s=s&"|[\xFE-\xFE].{0,5}([^\x80-\xBF]|$)"
s=s&"|[\x00-\x7F][\x80-\xBF]"
s=s&"|[\xC0-\xDF].[\x80-\xBF]"
s=s&"|[\xE0-\xEF]..[\x80-\xBF]"
s=s&"|[\xF0-\xF7]...[\x80-\xBF]"
s=s&"|[\xF8-\xFB]....[\x80-\xBF]"
s=s&"|[\xFC-\xFD].....[\x80-\xBF]"
s=s&"|[\xFE-\xFE]......[\x80-\xBF]"
s=s&"|^[\x80-\xBF]"
re.Pattern=s
is_valid_utf8=(Notre.Test(input))
EndFunction

s=read("utf-8.txt")'读取文件
WScript.Echois_valid_utf8(s)'判断是否UTF-8



+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


yu2n说道:2014年08月16日14:08[code]
'检察文件是否为UTF-8,有BOM/无BOM皆可,读取文件BOM头/前4Kbit判读
Functionis_valid_utf8(ByValfile)
is_valid_utf8=False
'将Byte()数组转成String字符串
Dimado,a(),i,n,Bin,s,re
Setado=CreateObject("ADODB.Stream")
ado.Type=1:ado.Open
ado.LoadFromFilefile
n=ado.Size-1
'检查空文件/限制读取4Kbit
Ifn=1024*4-1Thenn=1024*4-1'4Kbit
'使用BOM判断
Bin=ado.read(2)
IfAscB(MidB(Bin,1,1))=&HEFAndAscB(MidB(Bin,2,1))=&HBBThen
is_valid_utf8=True:ExitFunction
EndIf
'将Byte()数组转成String字符串
ReDima(n):ado.Position=0
Fori=0Ton
a(i)=ChrW(AscB(ado.Read(1)))
Next
'使用正则表达式判断
Setre=NewRegexp
s="[\xC0-\xDF]([^\x80-\xBF]|$)"
s=s&"|[\xE0-\xEF].{0,1}([^\x80-\xBF]|$)"
s=s&"|[\xF0-\xF7].{0,2}([^\x80-\xBF]|$)"
s=s&"|[\xF8-\xFB].{0,3}([^\x80-\xBF]|$)"
s=s&"|[\xFC-\xFD].{0,4}([^\x80-\xBF]|$)"
s=s&"|[\xFE-\xFE].{0,5}([^\x80-\xBF]|$)"
s=s&"|[\x00-\x7F][\x80-\xBF]"
s=s&"|[\xC0-\xDF].[\x80-\xBF]"
s=s&"|[\xE0-\xEF]..[\x80-\xBF]"
s=s&"|[\xF0-\xF7]...[\x80-\xBF]"
s=s&"|[\xF8-\xFB]....[\x80-\xBF]"
s=s&"|[\xFC-\xFD].....[\x80-\xBF]"
s=s&"|[\xFE-\xFE]......[\x80-\xBF]"
s=s&"|^[\x80-\xBF]"
re.Pattern=s
is_valid_utf8=(Notre.Test(Join(a,"")))
EndFunction

[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: