怎样判断字符串中含有非汉字字符?

时间:2022-09-23 22:52:28
用户输入一段汉字(GB或GBK),怎么能判断出是否含有非汉字字符?

15 个解决方案

#1


void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Label1->Caption="";
    unsigned char cTmp;
    for (int i=0; i<Edit1->Text.Length(); i++){
        cTmp = Edit1->Text.c_str()[i];
        if (cTmp > 0xa0){
            i++;
            }
        else{
               Label1->Caption="有非汉字 " ;
               break;
            }
        }
}
这样就可以,函数自己改写成你喜欢的

#2


来晚了,楼上正解。
原则:汉字的字符集大于0xa0,符号和英文数字相反。

#3


constantine 對于GB的漢字可以,對于GBK的某些字,比如"藝術"等繁體的,內碼是CB,87, D0, 67,
該如何判斷? 0x67 的ASC = 'g';

#4


GBK是繁體?BIG5才是繁體吧?
还有,你是不是没有看清楚我的代码,CB,D0才要判断,
        if (cTmp > 0xa0){
            i++;//------------------这里跳过了
            }
也就是说,判断第一个就行了

#5


要不你就再for里面改为i=i+2
好了也没有关系,因为一旦有非汉字你就不需要循环下去了
有非汉字,第一个非汉字肯定出现在奇位置上(不是相对i),
这样你明白了没有?

#6


Borland 的 AnsiString 是支持判断汉字的,简体繁体通用的,一个汉字两个字节
用 if(Edit1->Text.IsLeadByte(i)) 来判断第 i 个字符是否为汉字的前个字节
用 if(Edit1->Text.IsTrailByte(i)) 来判断第 i 个字符是否为汉字的后个字节

#7


to constantine(飘遥的安吉儿):

如果输入GB2312的汉字,你的判断程序是可以的。但现在的系统都支持GBK。
BIG5是*的汉字内码规范,很多人都认为繁体汉字就是BIG5码,实际是错误的,一个是点阵,一个是编码规范,两个完全不同的概念。
这是我新从网上找到的一段文字:
“GBK编码中不仅包括了原GB-2312编码,同时也包括了许多简码的繁体码,同时还有许多的符号与不常用汉字。GBK编码的范围是:高字节从0x81到0xFE,低字节从0x40到0xFE,同时不包括0x7F。”

所以我写的代码是:
int __fastcall CheckHZStr(BYTE *pStr)
{
    int Len = strlen(pStr);
    BOOL bHz;

    if (Len % 2 == 1)
    {
        return 0;
    }

    for (int i = 0; i < Len; i += 2)
    {
        bHz = (pStr[0] >= 0x81 && pStr[0] <= 0xfe &&
            pStr[1] >= 0x40 && pStr[1] <= 0xfe && pStr[1] != 0x7e);
        if (!bHz)
        {
            return 0;
        }
    }
    return Len>>1;
}

这段代码还不是很完善,因为在这个区域内,有的位置没有汉字,有的位置是符号而不是汉字,我只想判断是不是汉字,比如姓名(不包括标点符号).

#8


to ybchen(C++爱好者)(www.cppfans.com) :

你的代码能判断出汉字和英文字符,但不能判断是GBK、BIG5还是韩文等。

#9


To 楼上:
  给出一些字符的编码,你是无法知道它是GBK还是BIG5,或者是韩文。对于同一个编码,如果你将它看成是GBK码,它是某个汉字,如果看成是BIG5,那么它又是另外一个汉字,如果看成是韩文,它又是另外一个字。就好比10,如果将它看作十进制的数字,它是十,如果看成十六进制的数字,它是十六,如果看成八进制的数字,它是八,如果看成是二进制的,它又变成了二。
  有些软件,能够自动识别是哪种字符集,它的前提就是所有的字符,采用的是同一个编码(字符集),然后根据各个字符集的特性,来分析这段文字是哪种字符集。能够识别的另外一个条件就是,字的个数必须足够多,如果只是一两个字,它是无法判断的。

#10


很详细了,不要把自己的系统复杂化,没有万能的东西,也不需要万能的东西

#11


呵呵,这个还真不知道,没有怎么看过资料,其实我那个也只是判断编码而已,还是有问题的
标点也是不能判断的,
 ybchen(C++爱好者)(www.cppfans.com)
的方法你试试,这个我不知道

看来是帮不了你了!
你看看boost能不能帮上忙

#12


>>用户输入一段汉字(GB或GBK),怎么能判断出是否含有非汉字字符?

关键是楼主认为 “什么不是汉字字符”,
如果连全角符号也不包含的话,可以这样来判断:

AnsiString s="悱恻完成么我们厂";
WideString w=WideString(s);
DWORD      dw;

for(int i=1; i<w.Length(); ++i)
{
  dw=(DWORD)(w[i]);
  if(dw<=0x4E00 || dw>=0x95A5) //Unicode 码的“一”和“龥”
  {
    ShowMessage("存在非汉字!");
  }
}

#13


看来这个问题可以结束了,感谢各位大侠,感谢季大侠出手!

我在网上搜到了 “GBK 汉字内码扩展规范编码表(一)” 和 “GBK 汉字内码扩展规范编码表(二)”,慢慢研究,有兴趣的也可以下载看看。

再次感谢!

#14


myy() 的代码我研究研究。

#15


应该是:

if(dw<0x4E00 || dw>0x95A5) //Unicode 码的“一”和“龥”

Unicode 码 的 0x4E00 ~ 0x95A5 之间是20902 个汉字,
不包含全角符号、日文符号、制表符等...

可以看看这个:
http://www.ccrun.com/program/view.asp?id=23

#1


void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Label1->Caption="";
    unsigned char cTmp;
    for (int i=0; i<Edit1->Text.Length(); i++){
        cTmp = Edit1->Text.c_str()[i];
        if (cTmp > 0xa0){
            i++;
            }
        else{
               Label1->Caption="有非汉字 " ;
               break;
            }
        }
}
这样就可以,函数自己改写成你喜欢的

#2


来晚了,楼上正解。
原则:汉字的字符集大于0xa0,符号和英文数字相反。

#3


constantine 對于GB的漢字可以,對于GBK的某些字,比如"藝術"等繁體的,內碼是CB,87, D0, 67,
該如何判斷? 0x67 的ASC = 'g';

#4


GBK是繁體?BIG5才是繁體吧?
还有,你是不是没有看清楚我的代码,CB,D0才要判断,
        if (cTmp > 0xa0){
            i++;//------------------这里跳过了
            }
也就是说,判断第一个就行了

#5


要不你就再for里面改为i=i+2
好了也没有关系,因为一旦有非汉字你就不需要循环下去了
有非汉字,第一个非汉字肯定出现在奇位置上(不是相对i),
这样你明白了没有?

#6


Borland 的 AnsiString 是支持判断汉字的,简体繁体通用的,一个汉字两个字节
用 if(Edit1->Text.IsLeadByte(i)) 来判断第 i 个字符是否为汉字的前个字节
用 if(Edit1->Text.IsTrailByte(i)) 来判断第 i 个字符是否为汉字的后个字节

#7


to constantine(飘遥的安吉儿):

如果输入GB2312的汉字,你的判断程序是可以的。但现在的系统都支持GBK。
BIG5是*的汉字内码规范,很多人都认为繁体汉字就是BIG5码,实际是错误的,一个是点阵,一个是编码规范,两个完全不同的概念。
这是我新从网上找到的一段文字:
“GBK编码中不仅包括了原GB-2312编码,同时也包括了许多简码的繁体码,同时还有许多的符号与不常用汉字。GBK编码的范围是:高字节从0x81到0xFE,低字节从0x40到0xFE,同时不包括0x7F。”

所以我写的代码是:
int __fastcall CheckHZStr(BYTE *pStr)
{
    int Len = strlen(pStr);
    BOOL bHz;

    if (Len % 2 == 1)
    {
        return 0;
    }

    for (int i = 0; i < Len; i += 2)
    {
        bHz = (pStr[0] >= 0x81 && pStr[0] <= 0xfe &&
            pStr[1] >= 0x40 && pStr[1] <= 0xfe && pStr[1] != 0x7e);
        if (!bHz)
        {
            return 0;
        }
    }
    return Len>>1;
}

这段代码还不是很完善,因为在这个区域内,有的位置没有汉字,有的位置是符号而不是汉字,我只想判断是不是汉字,比如姓名(不包括标点符号).

#8


to ybchen(C++爱好者)(www.cppfans.com) :

你的代码能判断出汉字和英文字符,但不能判断是GBK、BIG5还是韩文等。

#9


To 楼上:
  给出一些字符的编码,你是无法知道它是GBK还是BIG5,或者是韩文。对于同一个编码,如果你将它看成是GBK码,它是某个汉字,如果看成是BIG5,那么它又是另外一个汉字,如果看成是韩文,它又是另外一个字。就好比10,如果将它看作十进制的数字,它是十,如果看成十六进制的数字,它是十六,如果看成八进制的数字,它是八,如果看成是二进制的,它又变成了二。
  有些软件,能够自动识别是哪种字符集,它的前提就是所有的字符,采用的是同一个编码(字符集),然后根据各个字符集的特性,来分析这段文字是哪种字符集。能够识别的另外一个条件就是,字的个数必须足够多,如果只是一两个字,它是无法判断的。

#10


很详细了,不要把自己的系统复杂化,没有万能的东西,也不需要万能的东西

#11


呵呵,这个还真不知道,没有怎么看过资料,其实我那个也只是判断编码而已,还是有问题的
标点也是不能判断的,
 ybchen(C++爱好者)(www.cppfans.com)
的方法你试试,这个我不知道

看来是帮不了你了!
你看看boost能不能帮上忙

#12


>>用户输入一段汉字(GB或GBK),怎么能判断出是否含有非汉字字符?

关键是楼主认为 “什么不是汉字字符”,
如果连全角符号也不包含的话,可以这样来判断:

AnsiString s="悱恻完成么我们厂";
WideString w=WideString(s);
DWORD      dw;

for(int i=1; i<w.Length(); ++i)
{
  dw=(DWORD)(w[i]);
  if(dw<=0x4E00 || dw>=0x95A5) //Unicode 码的“一”和“龥”
  {
    ShowMessage("存在非汉字!");
  }
}

#13


看来这个问题可以结束了,感谢各位大侠,感谢季大侠出手!

我在网上搜到了 “GBK 汉字内码扩展规范编码表(一)” 和 “GBK 汉字内码扩展规范编码表(二)”,慢慢研究,有兴趣的也可以下载看看。

再次感谢!

#14


myy() 的代码我研究研究。

#15


应该是:

if(dw<0x4E00 || dw>0x95A5) //Unicode 码的“一”和“龥”

Unicode 码 的 0x4E00 ~ 0x95A5 之间是20902 个汉字,
不包含全角符号、日文符号、制表符等...

可以看看这个:
http://www.ccrun.com/program/view.asp?id=23