C++如何过滤出字符串的中⽂(GBK、UTF-8)
前⾔
最近在处理游戏敏感词之类的东西,为了加强屏蔽处理,所以需要过滤掉字符串中的除汉字之外的是其他东西如数字,符号,英⽂字母等。
⾸先我查阅资料并写了个函数:
⽰例:返回输⼊字符串中汉字的个数:
std::string StrWithOutSymbol(const std::string &source)
{
string sourceWithOutSymbol;
int i = 0;
while (source[i] != 0)
{
if (source[i] & 0x80 )
{
sourceWithOutSymbol += source[i];
sourceWithOutSymbol += source[i + 1];
i += 2;
else
{
i ++;
}
}
return
sourceWithOutSymbol;
}
这个函数的原理是ord($str)&0x80来判断汉字
80对应的⼆进制代码为1000 0000,最⾼位为⼀,代表汉字汉字编码格式通称为10格式⼀个汉字占2字节,但只代表⼀个字符"Windows中,中⽂简体字符集的编码是同时⽤1个字节和2个字节来表⽰的。当⾼位是0x00~0x7f时,为⼀个字节,⾼位为
0x80以上时⽤2个字节表⽰"
当你发现⼀个字节的内容⼤于0x7f,那它肯定是个(跟另外⼀个字节拼凑成⼀个)汉字,如何判断肯定⼤于0x7f呢?
0x7f(1111111)后⾯⼀个数就是0x80(10000000),所以想要⼤于0x7f,这个字节的最⾼位都肯定是1,我们只需要判断这个最⾼位是否为1就⾏了。
判断⽅法:
位与(相同的位都是1的才为1,否则为0):lua字符串转数组
如:要判断⼀个数的第三位是否是1,只要跟4(100)位与,判断⼀个数的第2位是否为1就跟2(10)位与.
同理判断第⼋位是否为1只要跟(10000000)也就是0x80位与了.
这⾥为什么不⽤>0x7f?php可能还⾏,但在其他强类型语⾔⾥⾯,1个字节的最⾼位⽤来标⽰负数,⼀个负数肯定不可能⼤于0x7f(最⼤的整数)
再举个例⼦:
a的assic码是97(1100001)
A的assic码是65(1000001)
b的assic码是98(1100010)
B的assic码是66(1000010)
发现⼀个规律:⼀个a-z的字母,只要是⼩写字母,第六位肯定是1,我们可以⽤这个来判断⼤⼩写:
这时候只要跟⽤以个字母跟0x20(100000)来位与判断:
if(ord($a)&0x20){
//⼤写
}
如何把所有字母改成⼤写?第六位的1改成0就⾏了:
$a='a';
$a = chr(ord($a)&(~0x20));
echo $a;
然后我信⼼满满的吧这个函数加⼊到项⽬中去,点击运⾏,输⼊中⽂进⾏检查,当!项⽬报错了数组越界
这是为什么,我⼜定位到报错的地⽅,发现我使⽤的cocos-lua,在向c++传递字符串的时候传进来的字符串是以UTF-8来进⾏编码的,我⼜去UIF-8的编码规则发现
UTF-8编码规则:如果只有⼀个字节则其最⾼⼆进制位为0;如果是多字节,其第⼀个字节从最⾼位开始,连续的⼆进制位值为1的个数决定了其编码的字节数,其余各字节均以10开头。UTF-8转换表表⽰如下:
⽽我之前的是按照GBK编码进⾏操作的,GBK每个中⽂字符只占两个字节,⽽utf-8的话中⽂可能占3个字节,四个字节,甚⾄是五个六个,所以⽤刚才那样的函数就会有越界的情况发⽣,所以对⽤UTF-8进⾏编码的字符串,就需要进⾏另外的处理,所以我写了⼀个新函数:
对UTF-8编码的字符串进⾏中⽂筛选的函数:
std::string censorStrWithOutSymbol(const std::string &source)
{
string sourceWithOutSymbol;
int i = 0;
while (source[i] != 0)
{
if (source[i] & 0x80 && source[i] & 0x40 && source[i] & 0x20)
{
int byteCount = 0;
if (source[i] & 0x10)
{
byteCount = 4;
}
else
{
byteCount = 3;
}
for (int a = 0; a < byteCount; a++)
{
sourceWithOutSymbol += source[i];
i++;
}
}
else if (source[i] & 0x80 && source[i] & 0x40)
{
i += 2;
}
else
{
i += 1;
}
}
return sourceWithOutSymbol;
}
点击运⾏,成功了!舒服。
总结
以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作具有⼀定的参考学习价值,谢谢⼤家对的⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论