| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 406 人关注过本帖
标题:判断一个字符是否纯汉字(非标点符号、英数等)的函数
只看楼主 加入收藏
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:533
专家分:380
注 册:2013-10-4
结帖率:100%
收藏
 问题点数:0 回复次数:21 
判断一个字符是否纯汉字(非标点符号、英数等)的函数
类似这种基础函数,现在习惯交给DeepSeek来写了。
不知有无遗漏?——

FUNCTION IsPureChinese(tcChar)
* 判断输入参数是否为纯汉字?
* 注:只预设两种输入参数编码:GBK或UTF-8。
LOCAL llResult, lcChar

lcChar = ALLTRIM(tcChar)

IF EMPTY(tcChar)
    RETURN .F.
ENDIF

* 自动检测编码并调用相应函数
DO CASE
    CASE LEN(lcChar) = 1    && 单字节,肯定不是汉字
        RETURN .F.
        
    CASE LEN(lcChar) = 2    && 可能是GBK编码
        lcChar = strconv(lcChar, 9)    && 将双字节字符也转换为 UTF-8
        RETURN IsUTF8Chinese(lcChar)
        
    CASE LEN(lcChar) >= 3    && 可能是UTF-8编码
        RETURN IsUTF8Chinese(lcChar)
        
    OTHERWISE
        RETURN .F.
ENDCASE
ENDFUNC

* UTF-8编码汉字判断
FUNCTION IsUTF8Chinese(tcChar)
LOCAL lnByte1, lnByte2, lnByte3, lnLen, lnUnicode

lcUnicode = strconv(tcChar, 12)    && 将 UTF-8 转换为 Unicode
* 小端序:低位在前,高位在后
lnLow = ASC(SUBSTR(tcUnicodeStr, 1, 1))
lnHigh = ASC(SUBSTR(tcUnicodeStr, 2, 1))
lnUnicode = lnHigh * 256 + lnLow
* 汉字Unicode范围:0x4E00-0x9FFF
RETURN (lnUnicode >= 0x4E00 AND lnUnicode <= 0x9FFF)
ENDFUNC



[此贴子已经被作者于2025-11-18 12:09编辑过]

搜索更多相关主题的帖子: RETURN 判断 汉字 函数 编码 
昨天 14:52
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10854
专家分:43464
注 册:2014-5-20
收藏
得分:0 
汉字Unicode范围:0x4E00-0x9FFF
这个是 UTF16,不是 UTF-8 ?


昨天 15:11
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10854
专家分:43464
注 册:2014-5-20
收藏
得分:0 
这样看看有冇搞头
cstr  = "汉字"
uinc = STRCONV(cstr,5)
utf8 = STRCONV(cstr,9)
? STRCONV(STRCONV(cstr,6),5) == cstr
? STRCONV(STRCONV(uinc,6),5) == uinc
? STRCONV(STRCONV(utf8,6),5) == utf8

? STRCONV(STRCONV(cstr,11),9) == cstr
? STRCONV(STRCONV(uinc,11),9) == uinc
? STRCONV(STRCONV(utf8,11),9) == utf8
昨天 15:28
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:533
专家分:380
注 册:2013-10-4
收藏
得分:0 
以下是引用吹水佬在2025-11-17 15:11:21的发言:
汉字Unicode范围:0x4E00-0x9FFF
这个是 UTF16,不是 UTF-8 ?


没错!Deepseek在一开头偷了个懒:
lcUnicode = strconv(tcChar, 12)
其实这样是有风险的:事关,超出3字节的UTF-8,在转换成Unicode的过程中会有损。
只不过平时我也不太可能处理到4字节以上的UTF-8,睁一只眼闭一只眼,当睇唔见啦。
昨天 15:36
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:825
专家分:3264
注 册:2018-3-13
收藏
得分:0 
以下是引用cssnet在2025-11-17 14:52:48的发言:
* GBK汉字编码范围:
* 首字节:0xB0-0xF7
* 尾字节:0xA1-0xFE

不知你这是从哪位误人子弟的学者处抄来的
瞧瞧不用大字体都看不出差别的这哥俩,符合这扯蛋的编码范围不
? '丢',IsLeadByte('丢'), trans('丢', '@0')
? '丟',IsLeadByte('丟'), trans('丟', '@0')

大概率是把 GBK 和 GB2312 搞混了,但 GB2312 的首字节范围(0xA1-0xF7)也比它大

[此贴子已经被作者于2025-11-17 16:43编辑过]


这家伙很懒,啥也没留下
昨天 16:35
kangss
Rank: 8Rank: 8
等 级:贵宾
威 望:14
帖 子:383
专家分:887
注 册:2014-6-12
收藏
得分:0 
全角的标点符合、数字、字母,算不算汉字?

https://baike.baidu.com/item/全角/9323113
全角:是指中GB2312-80(《信息交换用汉字编码字符集·基本集》)中的各种符号,如A、B、C、1、2、3等,应将这些符号理解为汉字

“判断一个字符是否纯汉字(非标点符号、英数等)的函数”的意图是什么呢?
昨天 17:22
yiyanxiyin
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:9
帖 子:315
专家分:2302
注 册:2023-6-29
收藏
得分:0 
提问没有, 你应该这样问ds: 一段编码明确的文字(要么是utf8,要么是gbk), 怎么判断这段文字都是汉字

如果编码不明确, 那么这个问题会上升到一个很高的高度, 需要自动判断文字的编码, 文字少很难, 如果是大量的文字判断准确度会高一些

还有gbk就别考虑了, 都是淘汰的编码, 除非你的系统是个古董, 所以一发现ds给出的代码有判断编码, 那么你就应该立即补充你的问题:只考虑utf8
昨天 17:46
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:533
专家分:380
注 册:2013-10-4
收藏
得分:0 
以下是引用csyx在2025-11-17 16:35:56的发言:

不知你这是从哪位误人子弟的学者处抄来的
瞧瞧不用大字体都看不出差别的这哥俩,符合这扯蛋的编码范围不
? '丢',IsLeadByte('丢'), trans('丢', '@0')
? '丟',IsLeadByte('丟'), trans('丟', '@0')

大概率是把 GBK 和 GB2312 搞混了,但 GB2312 的首字节范围(0xA1-0xF7)也比它大


感谢指正!确实是我的疏忽!
代码是 DeepSeek 给的,我只看了 UTF-8(Unicode)部分,没留意到 GBK 有Bug。
当然,这函数只能针对常用汉字(即 Unicode 编码 0x4E00 ~ 0x9FA5 的20902个汉字),至于后来 Unicode 不断扩展的罕用字,搞得比较复杂,无兴致逐一去枚举。
其实 GBK 编码的Bug,解决方案也简单:

    CASE LEN(lcChar) = 2    && 可能是GBK编码
        lcChar = strconv(lcChar, 9)    && 将双字节字符也转换为 UTF-8
        RETURN IsUTF8Chinese(lcChar)
   
统一用 UTF-8(准确地说,最终是转换为Unicode)去判断即可。

补充一点:未提供容错处理,无法通用。比如说:若输入的字符参数本身就是2字节的 Unicode LE/BE,这么strconv()转来转去,全乱套了!从这一点也可以看出 UTF-8 相比 UTF-16 的优势了:
UTF-16有大尾和小尾(BE/LE)的区别;你随便输入一个2字节的字符参数,根本无法精准地确认:它究竟是ANSI?或者是 UTF-16 LE?或者是UTF-16 BE?然而,你随便输入一个 UTF-8 ,傻瓜都能立刻确认它是且仅是 UTF-8 !
昨晚 21:27
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:533
专家分:380
注 册:2013-10-4
收藏
得分:0 
以下是引用kangss在2025-11-17 17:22:15的发言:

“判断一个字符是否纯汉字(非标点符号、英数等)的函数”的意图是什么呢?


原本我跟 DeepSeek 讨论的是另一个问题:
输入一个汉字字符串,如何判断它是一句话,或是一段话(有两句或以上)?
考虑以下例外的情形:

我的天哪!!!
我的天哪!!!……
你难道不惭愧吗?!
你难道不惭愧吗!?

单纯依靠 OCCURS( [句末标志符号(。!?.!?)] ) ,无法准确判断汉字字符串是否有两句话以上;必须确认:在一个[句末标志符号]后边,又出现了至少一个纯汉字,才可断定它有两句或以上。
昨晚 21:47
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:533
专家分:380
注 册:2013-10-4
收藏
得分:0 
以下是引用csyx在2025-11-17 16:35:56的发言:
? '丢',IsLeadByte('丢'), trans('丢', '@0')
? '丟',IsLeadByte('丟'), trans('丟', '@0')


遇到一个有趣的问题——

? '丢' = 0hB6AA   && 返回值 .T.
? '丢' == 0hB6AA   && 返回值 .T.
? TRANSFORM(0hB6AA, "@0")   && 返回值 "B6AA"
? TRANSFORM('丢', "@0")   && 返回值 "丢"

这是什么原因?有没有办法,让 TRANSFORM('丢', "@0") 也返回 "B6AA" ?


翻了一下 VFP 帮助文档,原来如此——

? STRCONV('丢', 15)   && 返回值 "B6AA"
? TRANSFORM(STRCONV('丢', 15), "@0")   && 返回值 "B6AA"




[此贴子已经被作者于2025-11-17 22:47编辑过]

昨晚 22:20
快速回复:判断一个字符是否纯汉字(非标点符号、英数等)的函数
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017983 second(s), 9 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved