着急啊,中文字符串比较问题

Mrkang 2007-12-09 07:33:05
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
RichEdit1: TRichEdit ;
RichEdit2: TRichEdit;
procedure RichEdit2Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
Len,before:integer;

implementation

{$R *.dfm}

procedure TForm1.RichEdit2Change(Sender: TObject);
var
i,p:integer;
ws1,ws2:widestring;
begin
if p=0 then
begin
RichEdit1.SelStart:=0;
RichEdit1.SelLength:=Length(RichEdit2.Text);
RichEdit2.SelStart:=0;
RIchEdit2.SelLength:=Length(RichEdit2.Text);
if RichEdit1.SelText=Richedit2.SelText then
RichEdit1.SelAttributes.Color:=clred;
before:=Length(RichEdit2.Text);
RichEdit2.SelStart:=Length(RichEdit2.Text);
p:=2;
end
else begin
Len:=Length(Richedit2.Text)-before;
RichEdit1.SelStart:=before;
RichEdit1.SelLength:=len;
RichEdit2.SelStart:=before;
RichEdit2.SelLength:=Len;
if len<0 then
begin
RichEdit1.SelStart:=Length(RichEdit2.Text);
RichEdit1.SelLength:=0-len;
RichEdit1.SelAttributes.Color:=clNone;
end;
ws1:=widestring(RichEdit1.SelText);
ws2:=widestring(RichEdit2.SelText);
for i:=1 to Len do
begin
if ws1[i]=ws2[i] then
begin
RichEdit1.SelAttributes.Color:=clred;
showmessage(ws1[i]);//注释1
showmessage(ws2[i]);//注释2
end;
end;
before:=Length(Richedit2.Text);
RichEdit2.SelStart:=Length(RichEdit2.Text);
end;
end;

end.

以上代码可以编译通过,想达到的目的是在RichEdit2中输入RichEdit1中已经有的文字,如果输入的完全相同,则RichEdit1中的文字显示为红色,问题是这样的,如果RichEdit1中的文字是"你好",我在RichEdit2中输入"泥好",RichEdit1中的文字也会显示为红色,中文字符串的比较还有什么其他的方法吗?请指教
...全文
208 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
yjwtcham 2007-12-17
  • 打赏
  • 举报
回复
建议使用trim()函数试试
判断:
if trim(edit1.text) = trim(edit2.text) then
begin
...
end
else
begin
...
end;
Mrkang 2007-12-17
  • 打赏
  • 举报
回复
to neweipeng

============
谢谢了,老大,太清晰了....结贴
neweipeng 2007-12-16
  • 打赏
  • 举报
回复
汉字占2字节,英文占1字节,通过判断是否为汉字来决定进行比较的字节长度是否为2,
如下,逐个字符比较中英文混排
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
RichEdit2: TRichEdit;
Memo1: TMemo;
procedure RichEdit2Change(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
Start:integer=0; //字符比较的起始位置

implementation

{$R *.dfm}

procedure TForm1.RichEdit2Change(Sender: TObject);
var
i,comparelen,uicode:integer;
str1,str2:string;
IsSame:bool;
begin
if Length(Richedit2.Text)>Length(Richedit1.Text) then exit;
comparelen:=Length(Richedit2.Text)-Start;
if comparelen<0 then //RichEdit2的字符减少时
begin
Start:=Length(Richedit2.Text);
RichEdit1.SelStart:=Start;
RichEdit1.SelLength:=0-comparelen;
RichEdit1.SelAttributes.Color:=clNone;
end
else
begin
str1:=copy(RichEdit1.Text,start+1,comparelen);
str2:=copy(RichEdit2.Text,start+1,comparelen);
i:=1;
while(i<=comparelen)do
begin
if ord(str1[i])>160 then //判别是否为汉字,可能不是160
begin
uicode:=2; //占2字节
if(str1[i]=str2[i])and(str1[i+1]=str2[i+1]) then
IsSame:=True
else
IsSame:=False;
end
else //非汉字
begin
uicode:=1; //占一个字节
if(str1[i]=str2[i]) then
IsSame:=True
else
IsSame:=False;
end;
if(IsSame) then
begin
RichEdit1.SelStart:=Start;
RichEdit1.SelLength:=uicode; //分别逐个比较,包括汉字和其他字符
RichEdit1.SelAttributes.Color:=clred;
end;
inc(Start,uicode);
inc(i,uicode);
end;

end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
RichEdit2.Text:='';
end;

end.
Mrkang 2007-12-14
  • 打赏
  • 举报
回复
to 飞雨
以上语句只需如此:

if RichEdit1.SelText=RichEdit2.SelText then
RichEdit1.SelAttributes.Color:=clred
else
……

======
这样的方法确实是可以的,但是当你输入词的时候,如果有一个字是对的,有一个词是错的,那也认为是都对的,或者是都错的,如何处理呢。..

感谢大家的帮忙,非常感谢!!~~~~~~
sy_100000 2007-12-11
  • 打赏
  • 举报
回复
if p=0 then之前,p就没有初始化。函数内变量是不会自动初始化的,而是一个随机数,所以p=0的几率是很小的。另外,Delphi的RichEdit并不支持Unicode,没必要转换成Widestring来比较。只需

if RichEdit1.SelText=RichEdit2.SelText then 或

if StrComp(PChar(RichEdit1.SelText),PChar(RichEdit2.SelText)=0 then

另外,建议不要用VCL的showMessage或MessageDlg,因为showMessage或MessageDlg出现的按钮文字,还得处理本地化问题,否则是英文的(比如OK,Canvel、Yes、No等等)。而使用API的MessageBox或MessageBoxW,完全不用考虑本地化问题。VCL的showMessage或MessageDlg完全是多此一举甚至是画蛇添足!

楼主的以下语句,是只要RichEdit1.SelText与RichEdit2.SelText之中有一个以上的字符相同就使
RichEdit1.SelAttributes.Color:=clred;所以“你好”\“泥好”也变红,因为有“好”字相同。

ws1:=widestring(RichEdit1.SelText);
ws2:=widestring(RichEdit2.SelText);
for i:=1 to Len do
begin
if ws1[i]=ws2[i] then
begin
RichEdit1.SelAttributes.Color:=clred;
showmessage(ws1[i]);//注释1
showmessage(ws2[i]);//注释2
end;
end;


以上语句只需如此:

if RichEdit1.SelText=RichEdit2.SelText then
RichEdit1.SelAttributes.Color:=clred
else
……
dirt 2007-12-10
  • 打赏
  • 举报
回复
if RichEdit1.SelText=Richedit2.SelText then
RichEdit1.SelAttributes.Color:=clred;

这句前面加上个ShowMessage(RichEdit1.SelText + '|||' +Richedit2.SelText)看看结果
Mrkang 2007-12-10
  • 打赏
  • 举报
回复
实际上问题就是下面这个,大家试一下,showmessage看到的有空字符还有问号,这是为什么
procedure TForm1.Button1Click(Sender: TObject);
var
s1,s2:widestring;
i:integer;

begin
s1:=RichEdit1.Text;
s2:=RichEdit2.Text;
for i:=1 to Length(richEdit1.Text) do
if s1[i]=s2[i] then
showmessage(s1[i])
end;
firetop818 2007-12-10
  • 打赏
  • 举报
回复
当你把for i:=1 to Length(richEdit1.Text) do改成for i:=1 to Length(s1) do 的时候,你再试试看
firetop818 2007-12-10
  • 打赏
  • 举报
回复
关键是你的这条语句for i:=1 to Length(richEdit1.Text) do中的Length(richEdit1.Text),你前面s1,s2是widestring类型,可你richEdit1.Text仍然是string类型啊
Mrkang 2007-12-10
  • 打赏
  • 举报
回复
没作用的,up
hongqi162 2007-12-10
  • 打赏
  • 举报
回复
使用pos看返回值
kshuangshuzhen 2007-12-10
  • 打赏
  • 举报
回复
顶一下
Mrkang 2007-12-10
  • 打赏
  • 举报
回复
实际上问题就是下面这个,大家试一下,showmessage看到的有空字符还有问号,这是为什么
procedure TForm1.Button1Click(Sender: TObject);
var
s1,s2:widestring;
i:integer;

begin
s1:=RichEdit1.Text;
s2:=RichEdit2.Text;
for i:=1 to Length(richEdit1.Text) do
if s1[i]=s2[i] then
showmessage(s1[i])
end;

=========

大家说的好像都不对啊,问题就处在上面这段代码上。汉字和字母确实是占用的字节不一样的,但是我用的是widestring类型。字符比较应该没问题啊
dirt 2007-12-10
  • 打赏
  • 举报
回复
我觉得最大的可能是RichEdit的HideSelection被设置为True造成的
agang200008 2007-12-10
  • 打赏
  • 举报
回复
转换我WideString类型后在比较
firetop818 2007-12-10
  • 打赏
  • 举报
回复
一个汉字两个字节,所以Length(s1),Length(Edit1.Text)长度是不一样的
procedure TForm1.Button1Click(Sender: TObject);
var
s1,s2:widestring;
i:integer;
begin
s1:=Edit1.Text;
s2:=Edit2.Text;
if s1 = s2 then
begin
for i:=1 to Length(s1) do
begin
showmessage(s1[i]);
end;
end;
end;
end.
Mrkang 2007-12-09
  • 打赏
  • 举报
回复
up
vistart 2007-12-09
  • 打赏
  • 举报
回复
重构一下算法吧

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧