Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请问能根据部分汉字(并不是部首的汉字),查询相关汉字吗,如“每”,查到:海,诲,侮,梅,晦,莓,悔,敏 #292

Open
zliu1022 opened this issue Oct 29, 2024 · 7 comments

Comments

@zliu1022
Copy link

zliu1022 commented Oct 29, 2024

请问能根据部分汉字(并不是部首的汉字),查询相关汉字吗
如“每”,可以查询到:海,诲,侮,梅,晦,莓,悔,敏,霉,毓,酶

部首只是没有计算机时候对待汉字的检字方式,
汉字应该根据造字方式来进行快速查找和关联,这才是汉字的重要魅力
也就是通过:象形、指事、会意、形声、转注和假借
其中的核心就是字形、甚至局部的形状,这并不仅仅限于少量的偏旁部首

补充下,为什么我会这么使用,而不是通过惯常的部首来找字
汉字的魅力之一就是象形,
通过象形可以了解华夏先民是怎么认识这个世界,并对世界进行抽象描述的,
这也是最重要的东西方文化差异之一

比如甲骨文“母”,是一个跽坐的女性,
然后引申出“每”,是一个跽坐女性的头发高高束起,

自然我就会想到怎么来看待和解读同样使用了“每”的同类汉字,
我推测他们应该有类似的意思,但“每”并不是偏旁部首
因此无法通过通用的部首来检索其他字

作为类比
殷契文渊——甲骨文大数据里面有通过AI算法,
在16万片甲骨片中寻找相关图形,
但对于规范汉字不需要AI,只需要整理每个字的字元即可,
但是字元的范围要比部首大,
这样整个汉字体系就可以像网络一样互相关联起来了

附上其他著名汉字网站的查询结果哈

感谢您的回复呀

@theajack
Copy link
Owner

没有现成的API,通过order插件简单封装一下就可以实现 @zliu1022
image

@theajack
Copy link
Owner

@zliu1022 这个只是判断包含关系的 要查每一个的这样封装
image

@theajack
Copy link
Owner

后续这两个我会封装到 api 里

@zliu1022
Copy link
Author

zliu1022 commented Oct 30, 2024

谢谢您的回复

我扩展了下,既可以匹配单个字,也可以匹配单个字里面的某几个笔划,比如找“梳”的右半边“”,“㐬”的上半部份“𠫓”,“㐬”的下半部分

cnchar_order % ./index.js 梳 5 11
查询字符: 梳
笔画范围: 第5笔到第11笔
结果数量: 12
结果列表: 流,梳,琉,巯,疏,硫,锍,旒,毓,蔬,鎏,醯
cnchar_order % ./index.js 梳 5 8 
查询字符: 梳
笔画范围: 第5笔到第8笔
结果数量: 27
结果列表: 充,弃,育,统,茺,桎,流,唷,梳,琉,窒,铳,巯,疏,硫,蛭,锍,旒,毓,撤,澈,膣,蔬,辙,鎏,醯,堉
cnchar_order % ./index.js 梳 9 11
查询字符: 梳
笔画范围: 第9笔到第11笔
结果数量: 16
结果列表: 侃,荒,流,梳,琉,谎,巯,慌,疏,硫,锍,旒,毓,蔬,鎏,醯

代码如下:

#!/opt/homebrew/bin/node

var cnchar = require('cnchar');
var order = require('cnchar-order');

cnchar.use(order);

// 获取命令行参数
var args = process.argv.slice(2); // 获取从第三个参数开始的命令行参数

var inputChar;
var startIndex;
var endIndex;

if (args.length === 0) {
    // 如果没有输入参数,默认为 "每"
    inputChar = '每';
    startIndex = undefined;
    endIndex = undefined;
} else if (args.length === 1) {
    // 如果输入了一个参数
    inputChar = args[0];
    startIndex = undefined;
    endIndex = undefined;

    // 检查是否是单个汉字
    if (inputChar.length !== 1 || !cnchar.isCnChar(inputChar)) {
        console.error('错误:请输入单个汉字作为查询字符。');
        process.exit(1);
    }
} else if (args.length === 2) {
    // 如果输入了两个参数,输出错误
    console.error('错误:输入了两个参数,这是无效的。请只输入一个参数(单个汉字),或输入三个参数(汉字,开始笔画数,结束笔画数)。');
    process.exit(1);
} else if (args.length === 3) {
    // 如果输入了三个参数
    inputChar = args[0];
    startIndex = parseInt(args[1], 10); // 将第二个参数转换为数字
    endIndex = parseInt(args[2], 10);   // 将第三个参数转换为数字

    // 验证输入的汉字
    if (inputChar.length !== 1 || !cnchar.isCnChar(inputChar)) {
        console.error('错误:第一个参数必须是一个单个汉字。');
        process.exit(1);
    }

    // 验证开始和结束笔画数是否为有效数字
    if (isNaN(startIndex) || isNaN(endIndex)) {
        console.error('错误:第二个和第三个参数必须是数字,表示开始和结束的笔画数。');
        process.exit(1);
    }

    if (startIndex < 1 || endIndex < startIndex) {
        console.error('错误:开始笔画数必须大于等于1,结束笔画数必须大于等于开始笔画数。');
        process.exit(1);
    }
} else {
    // 输入了超过三个参数,输出错误
    console.error('错误:输入的参数过多。');
    process.exit(1);
}

function query(a, start, end) {
    const orders = cnchar.order.dict.orders;

    let o = cnchar.stroke(a, 'order');

    // 如果返回的是数组,取第一个元素(对单个汉字应该只有一个)
    if (Array.isArray(o)) {
        o = o[0];
    }

    // 如果指定了开始和结束笔画数,截取对应的笔画
    if (start !== undefined && end !== undefined) {
        // 调整索引,从零开始,并且 slice 的结束索引是非包含的
        o = o.slice(start - 1, end); // 提取从第 start 笔到第 end 笔的笔画
    }

    const results = [];
    for (let w in orders) {
        const v = orders[w];
        if (v.length < o.length) continue;
        if (v.indexOf(o) !== -1) {
            results.push(w);
        }
    }
    return results;
}

let ret = query(inputChar, startIndex, endIndex);

// 输出结果
console.log(`查询字符: ${inputChar}`);
if (startIndex !== undefined && endIndex !== undefined) {
    console.log(`笔画范围: 第${startIndex}笔到第${endIndex}笔`);
}
console.log(`结果数量: ${ret.length}`);
console.log(`结果列表: ${ret.join(',')}`);

@zliu1022
Copy link
Author

反文旁好像匹配的不准确,很多字并没有这个部件

cnchar_order % ./index.js 敏 8 11
查询字符: 敏
笔画范围: 第8笔到第11笔
结果数量: 161
结果列表: 夭,攵,乔,厌,夹,庆,收,妖,妗,孜,岙,攸,改,攻,沃,饫,侠,侨,戾,放,枚,牧,玫,败,陕,举,契,娇,峡,峤,恹,挟,挢,政,故,浃,狭,畋,荚,荞,袄,骄,效,敉,敌,敖,桥,笑,致,莜,获,轿,做,厣,唳,庵,悠,捩,敏,救,敕,教,敛,敝,敢,矫,硖,赦,跃,铗,傲,婺,敞,散,敦,敬,葜,蛱,骛,嗷,廒,微,愍,敫,数,楔,榉,煞,禊,筱,誉,骜,儆,嫠,嫩,弊,撇,撖,潋,澉,熬,瘗,瞀,綮,肇,蔹,蔽,赘,锲,鹜,墩,徵,憋,憨,撒,撤,敷,橄,澈,獠,蝥,靥,鞒,馓,魇,徼,憝,擎,擞,整,暾,氅,激,瞥,瞰,缴,聱,薇,薮,螯,辙,徽,檄,礅,繁,螫,镦,蹩,鳌,警,鳖,鳘,蘩,霰,鑫,慜,硚,啟,漖,澂,姈
cnchar_order % ./index.js 攵     
查询字符: 攵
结果数量: 161
结果列表: 夭,攵,乔,厌,夹,庆,收,妖,妗,孜,岙,攸,改,攻,沃,饫,侠,侨,戾,放,枚,牧,玫,败,陕,举,契,娇,峡,峤,恹,挟,挢,政,故,浃,狭,畋,荚,荞,袄,骄,效,敉,敌,敖,桥,笑,致,莜,获,轿,做,厣,唳,庵,悠,捩,敏,救,敕,教,敛,敝,敢,矫,硖,赦,跃,铗,傲,婺,敞,散,敦,敬,葜,蛱,骛,嗷,廒,微,愍,敫,数,楔,榉,煞,禊,筱,誉,骜,儆,嫠,嫩,弊,撇,撖,潋,澉,熬,瘗,瞀,綮,肇,蔹,蔽,赘,锲,鹜,墩,徵,憋,憨,撒,撤,敷,橄,澈,獠,蝥,靥,鞒,馓,魇,徼,憝,擎,擞,整,暾,氅,激,瞥,瞰,缴,聱,薇,薮,螯,辙,徽,檄,礅,繁,螫,镦,蹩,鳌,警,鳖,鳘,蘩,霰,鑫,慜,硚,啟,漖,澂,姈

@zliu1022
Copy link
Author

看了下你的代码,也是有匹配问题的,比如找“每”,找到了“姆”
不知道是否能修改这个呀

@zliu1022 这个只是判断包含关系的 要查每一个的这样封装 image

@theajack
Copy link
Owner

@zliu1022 是的 因为目前是按照笔画匹配的 不是按照字来匹配的 所以避免不了这个问题
目前的字库里没有这中数据

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants