wordnet-php

需求很简单,解决很粗暴。

把wordnet db file导入到mysql数据库中

文件分为两种,
index.* 索引文件 除了index.sense
data.* 数据文件
所以,表也就两个。
但是,wordnet有*.exc文件,也就是单词的变形。在我这,这个需求被砍了。。。被砍的还有上下位词啊什么语义语素方面的东西,那些单词没有中文解释。。不过,sql表结构还是遵从源文件的数据格式的,所以数据没有缺失。
嗯,只关注了这两种文件,所以那些语义语素之类的暂时抛弃了。

读文件,按空格切成数组,读字段,生成sql插入语句,执行插入。
因为需要大量插入,所以,调大了max_allowed_packet,表使用InnoDB引擎。插入效率棒棒哒。
这只是整理数据,具体的界面还没有放到github上。
上代码,TL;DR

function index($line)
{
    global $sql;
    $one=explode(' ',$line);//空格作为分隔符
    
    $lemma = $sql->escape_string($one[0]);//转义lemma,有些单词包含单引号
    
    $pos = $one[1];
    
    $synset_cnt = $one[2];
    
    $ptr_cnt = $one[3]*1;//指针个数为十进制,*1转为int类型
    
    $ptr = '';
    if($ptr_cnt!=0){
        for($i=0;$i<$ptr_cnt;$i++){
            $ptr .= '"'.$one[$i+4].'",';
        }
    }
    $ptr = $ptr!=''?$sql->escape_string('['.trim($ptr,',').']'):null;
    $sense_cnt = $one[$ptr_cnt+4]*1;
    
    $tagsense_cnt = $one[$ptr_cnt+5]*1;
    
    $offset = '';
    for($i=0;$i<$synset_cnt;$i++){
        $offset .='"'.$one[$i+6+$ptr_cnt].'",';
    }
    $offset = '['.trim($offset,',').']';
    
    $value = "('$lemma','$pos','$synset_cnt','$ptr_cnt','$ptr','$sense_cnt','$tagsense_cnt','$offset'),";
    
    return $value;
}
function data($line)
{
    global $sql;
    $one = explode('|',$line); //先以 | 作为分隔符分开大部分字段和gloss字段,分别单独处理
    $data = explode(' ',$one[0]); //再以空格分开
    
    $offset = $data[0];
    
    $lex_filenum = $data[1]*1;
    
    $ss_type = $data[2];
    
    $w_cnt = hexdec($data[3]);
    
    $word_max = $w_cnt*2+3;// $w_cnt*2-1+4
    $word = array_slice($data,4,$w_cnt*2);
    $word = array_chunk($word,2);
    /* just get word , remove lex_id 这段注释里的代码只获取单词,不获取分词id
    $countWord = count($word);$w='';
    for($i=0;$i<=$countWord;$i+=2){
        if($i==$countWord)
            break;
        $w[]=$word[$i];
    }
    */
    $word = $sql->escape_string(json_encode($word));
    
    $p_cnt = $data[$word_max+1]*1;
    
    $ptr="";
    if($p_cnt!=0){
        $ptr = array_slice($data,$word_max+2,$p_cnt*4);
        $ptr = array_chunk($ptr,4);
        $ptr = json_encode($ptr);
    }
    
    $frames = "";
    $f_cnt = 1*$data[$w_cnt*2+$p_cnt*4+5]; //$w_cnt*2+4+$p_cnt*4+1
    if($f_cnt!=0){
        $frame = array_slice($data,$w_cnt*2+$p_cnt*4+6,$f_cnt*3);
        $countFrame = count($frame);
        for($i=0;$i<$countFrame;$i+=3){
            $frames[]=($i<$countFrame)?array_merge([$frame[$i+1]],[$frame[$i+2]]):'';
        }
        $frames = json_encode($frames);
    }
    
    $gloss = explode(';',trim($one[1])); //gloss分为单词定义和例句,用分号分隔。目前3.1有些单词包含了冒号,应该是打错了。。有些用冒号代替了分号,这绝对是打错了。。
    $definition = '';
    $sentence = '';
    $countGloss = count($gloss);
    for($j=0;$j<$countGloss;$j++){
        $gloss[$j] = trim($gloss[$j]);
        /* a little bug; so ...有些单词定义包含了双引号,所以这段注释了
        if(preg_match('#^[\"]#',trim($gloss[$j]))){
            $sentence[]=$gloss[$j];
        }else{
            $definition=$gloss[$j];
        }
        */
        //$j==0?$definition=$gloss[$j]:$sentence[]=$gloss[$j]; //a little bug too.. like offset='09560255' 有些单词定义不止一个,所以,这个也注释了
        preg_match('#^"(.*)"$#', $gloss[$j])?$sentence[]=$gloss[$j]:$definition[]=$gloss[$j];
    }
    $definition = $sql->escape_string(json_encode($definition));
    $sentence = $sentence==""?null:$sql->escape_string(json_encode($sentence));
    
    $value = "('$offset', $lex_filenum, '$ss_type', $w_cnt, '$word', $p_cnt, '$ptr', $f_cnt, '$frames', '$definition','$sentence'),";
    return $value;
}

项目地址 http://github.com/sleepm/wordnet-php

发布者

gt

QQ: 1520667045 一个名叫坏人的博客,他很想成为WEB攻城狮,因为他认为每个前端开发者的审美观都是很挑的……

发表评论

您的电子邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据