呵呵,不好意思,是我考虑不周。的确应该判断每个字符的类型。其实问题就集中在ByteType函数上,单就你的问题来说,可以专门写一个基于GBK字符集的GBKByteType函数:在这个函数里面,用专用于GBK字符集的GBKLeadBytes 变量来取代原来的LeadBytes 变量。其实所谓的LeadBytes 其实就是一个包含了系统默认语言字符集中,第一个字节所有可能的取值。因此,当我们初始化我们自己的专用于GBK字符集的GBKLeadBytes 变量的时候,可以将GBK编码标准中,第一个字节编码范围内的所有取值加入这个GBKLeadByte 集合即可。
下面这个是我刚写的一个程序,里面就自己重写了ByteType和Pos函数(分别命名为GBKByteType和GBKPos),其实也很简单,只要把里面对LeadBytes变量的引用改成对GBKLeadByte变量的引用就可以了。看看是不是能对你的程序有所帮助?
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
RadioGroup1: TRadioGroup;
Button2: TButton;
Button3: TButton;
Label1: TLabel;
Label2: TLabel;
procedure RadioGroup1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
GBKLeadBytes:set of char;
function GBKByteTypeTest(P
Char;Index:Integer):integer;
function GBKByteType(S:string;Index:integer):integer;
function GBKPos(SubStr,S:string):integer;
implementation
{$R *.dfm}
function GBKByteTypeTest(P
Char;Index:Integer):integer;
var
I: Integer;
begin
Result := 0;
if (P = nil) or (P[Index] = #$0) then Exit;
if (Index = 0) then
begin
if P[0] in GBKLeadBytes then Result := 1;
end
else
begin
I := Index - 1;
while (I >= 0) and (P
in GBKLeadBytes) do Dec(I);
if ((Index - I) mod 2) = 0 then Result := 2
else if P[Index] in GBKLeadBytes then Result := 1;
end;
end;
function GBKByteType(S:string;Index:integer):integer;
begin
Result:=0;
if SysLocale.FarEast then
Result:=GBKByteTypeTest(PChar(S), Index-1);
end;
function GBKPos(SubStr,S:string):integer;
var
i,j,Posi,StrLen,SubStrLen:integer;
begin
if (SubStr<>'') and (S<>'') then
begin
StrLen:=Length(S);
SubStrLen:=Length(SubStr);
Posi:=0;
i:=1;
While (i+SubStrLen-1<=StrLen) and (Posi<1) do
begin
if (GBKByteType(S,i)=GBKByteType(SubStr,1))
and
(S=SubStr[1])
then
begin
Posi:=i;
j:=2;
inc(i);
While (j<=SubStrLen)
and
(GBKByteType(S,i)=GBKByteType(SubStr,j))
and
(S=SubStr[j])
do
begin
inc(i);
inc(j)
end;
if j<=SubStrLen then
Posi:=0
end
else
inc(i)
end;
Result:=Posi
end
else
Result:=0
end;
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
case RadioGroup1.ItemIndex of
0:
begin
Edit1.Text:='|';
Edit2.Text:='億'
end;
1:
begin
Edit1.Text:='卫';
Edit2.Text:='何丽'
end
end
end;
procedure TForm1.FormShow(Sender: TObject);
begin
RadioGroup1.OnClick(Application)
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(inttostr(Pos(Edit1.Text,Edit2.Text)))
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
showmessage(inttostr(AnsiPos(Edit1.Text,Edit2.Text)))
end;
procedure TForm1.FormCreate(Sender: TObject);
var
GBKLeadByte:char;
begin
GBKLeadBytes:=[];
for GBKLeadByte:=Chr($81) to Chr($FE) do
Include(GBKLeadBytes,GBKLeadByte)
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
showmessage(inttostr(GBKPos(Edit1.Text,Edit2.Text)))
end;
end.