一个奇怪的问题-如何区分可显示和不可显示字符(300分)

  • 主题发起人 主题发起人 netexplorer
  • 开始时间 开始时间
N

netexplorer

Unregistered / Unconfirmed
GUEST, unregistred user!
有一段文本,其中包括英文字符,中文字符,以及不可显示的字符,我要将其
用一对单引号括起来作为SQL语句的查询匹配条件,例如str:='123qwe网 ',
在网字后面是一个不可显示的字符,由两个大于128的字节构成,现在我要
将这个不可显示的字符去掉,使得str:='123qwe网',但如果是空格则不去掉。
怎么做呢?
 
>>在网字后面是一个不可显示的字符,由两个大于128的字节构成,
那就没办法啦.你的所谓的"不可显示"字符是个汉字. (GB码汉字都是由两个
大于128的字节构成的). 所以没法将"雨"和这个"不可显示"的汉字区分开来.
 
我想你最好将GB码汉字表仔细研究一下,我想汉字在安排码顺序时有其特定的规律,
应该不会将可显示的汉字与不显示的汉字混排,看看有没有规律.有规律就好办,没有
的话那就没办法了.
 
Trim 函数时将 小于等于 ' ' (空格) 的字符去掉的
 
Pipi.兄,他说的是汉字.不能使用Trim.
 
汉字也可以显示呀,所谓不显示字符,我认为就是控制字符和' '
也就是#0..#32.
 
我研究了GB的编码,没有什么规律呀,再说,有没有什么更直接的办法呢?
 
我的看法:小于等于空格的算不能显示,大于空格的算可以显示
 
str:='123qwe网 ';
如果 (字符>128)and(字符<160) 则删除该字符
如果 字符是空格 则不删除
 
LSS:汉字都大于160吗?

我觉得,可以判断一下最后一个字符是不是汉字的LeadByte,是的话就删除。
这样应该就可以了吧。
 
看完了,也不知道 不可显示字符 到底指什么?
我本人赞同Pipi.的观点:小于等于空格的算不能显示,大于空格的算可以显示

如果指的是半个汉字,不知DreamTiger有何良方判断一个字符是不是汉字的LeadByte,
以前在Foxpro中我一般是从头到尾顺序计算大于128的字符个数,若为单数则
最后一个字符为汉字的LeadByte。
 
请教一下,什么是汉字的LeadByte,对于LeadByte和本问题有什么关系?
 
leadbyte是前导字符……
 
举个例子,有一个字符串,这里我无法将其写出来,就写出字符串的ASCII码如下:
39 179 181 203 190 187 250 255 211 39 44 。其中39代表引号字符,在两个
39之间有三个可显汉字,占用6个字节(179 181 203 190 187 250),然后的255,
211不可显,同时引号也变的不可显。这里就需要将字符串中的不可显字符(255,
211)消除,使得引号(39)可以显示出来。怎么做呢?
再提供一个含有不可显字符的例子如下:
39 190 173 192 237 214 250 192 237 163 175 188 39 44
 
to netexplorer: if aChar in LeadByte then // 如果是 LeadByte

to DreamTiger: 如果是中间某个字出现乱码呢?

有一个方法是,先判断一个 Char 是否是合法的 Char
if AChar in ['a'..'z', 'A'..'Z', #32, 等...]
如果是 LeadByte 再判断该汉字是否可以正确显示;
可以在一个 Bitmap.Canvas 上 TextOut,如果该 Bitmap 的像素点颜色都
与背景色相同的话,那么应该可以断定是一个无法显示的汉字。
(多么老土的办法!^_^) 但是无法区分显示出的乱码(如“□”)

我自己有另外一个比较土的办法,只是检查一个字符串里
是否都是合法的汉字,基本上管用,但偶尔会将个别正常的
汉字检查错,需要进一步完善,if 你改好了,请 E-mail 给我,
先谢了!


const
GBMax = '$F7FE';
// '$D7FE'
// '$D7FA'
GBMin = '$B0A1';


function CheckStr(s: string): Boolean;
var
i: Integer;
len: Integer;
chL, ch: Char;

function CheckDBChar(ch1, Ch2: Char): Boolean;
var
s: String;

function GetByteStr(c: Char): String;
begin
Result := EmptyStr;
Result := Format('%x', [Ord(c)]);
end;

begin
//Result := ((Ord(ch1) >= $B0) and (Ord(ch2) >= $A1)) and ((Ord(ch1) <= $F7) and (Ord(ch2) <= $FE));
s := '$' + GetByteStr(ch1) + GetByteStr(ch2);
Result := ((s <= GBMax) and (s >= GBMin)) and ((s > '$D7FE') or (s < '$D7FA'));
end;

begin
Result := True;
len := Length(s);
// 如果长度小于 2 ,肯定不是中文
if len < 2 then begin
Result := False;
Exit;
end;
i := 1;
while i < len do
begin
chL := s;
ch := s[i + 1];
Result := CheckDBChar(chL, ch);
if not Result then
Break;
inc(i, 2);
end;
end;

 
Big_Z:不能直接用if aChar in LeadByte then 来进行判断,要用
function ByteType(const S: string; Index: Integer): TMbcsByteType;
进行判断。

你的程序没有考虑中英文混排的问题。
 
多人接受答案了。
 
后退
顶部