版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1334589
陈同学将hanlp做成了服务:https://gitee.com/Erichan/EngineerCMS-HanLPService
用golang应用提交文字给这个hanlp服务,返回json数据格式的依存句法分析结果。
//这个是专门解析json的
package main
import (
"encoding/json"
"fmt"
"log"
"net/url"
"github.com/astaxie/beego/httplib"
)
type Dict struct {
SBV []HanlpJson
VOB []HanlpJson
IOB []HanlpJson
FOB []HanlpJson
DBL []HanlpJson
ATT []HanlpJson
ADV []HanlpJson
CMP []HanlpJson
COO []HanlpJson
POB []HanlpJson
LAD []HanlpJson
RAD []HanlpJson
IS []HanlpJson
HED []HanlpJson
}
type HanlpResult struct {
Result HanlpWord `json:"result"`
}
type HanlpWord struct {
Word []HanlpJson `json:"word"`
}
//用于json数据解析
type HanlpJson struct {
ID int64
LEMMA string
CPOSTAG string
POSTAG string
HEAD Json
DEPREL string
NAME string
}
type Json struct {
ID int64
LEMMA string
CPOSTAG string
POSTAG string
DEPREL string
NAME string
}
type Ltp2 struct {
Ltptwo []Ltp1
}
type Ltp1 struct { //这个办法不行,保留!
Ltpone []Ltp
}
type Ltp struct {
Id int64 `json:"id"`
Cont string `json:"cont"`
Pos string `json:"pos"`
Ne string `json:"ne"`
Parent int64 `json:"parent"`
Relate string `json:"relate"`
Semparent int64 `json:"semparent"`
Semrelate string `json:"semrelate"`
Arg []Arg1 `json:"arg"`
Sem []Sem1 `json:"sem"`
}
type Sem1 struct {
Id int64 `json:"id"`
Parent int64 `json:"parent"`
Relate string `json:"relate"`
}
type Arg1 struct {
Id int64 `json:"id"`
Type string `json:"type"`
Beg int64 `json:"beg"`
End int64 `json:"end"`
}
func main() {
link := url.QueryEscape("输水干线从佛山市顺德区杏坛镇西江干流中央的鲤鱼洲岛端部取水")
req := httplib.Post("http://localhost:8888/max?sentence=" + link)
str, err := req.String()
if err != nil {
log.Fatal(err)
}
// fmt.Println(str)
//json字符串解析到结构体
var hanlpresult HanlpResult
err = json.Unmarshal([]byte(str), &hanlpresult)
if err != nil {
log.Fatal(err)
}
// fmt.Println(hanlpresult.Result.Word)
hanlp := hanlpresult.Result.Word
dict := make([]Dict, 0)
for _, w := range hanlp {
dict1 := make([]Dict, 1)
for _, x := range hanlp {
if w.ID == x.HEAD.ID {
list1 := make([]HanlpJson, 1)
list1[0] = x
switch x.DEPREL {
case "主谓关系":
dict1[0].SBV = list1
case "动宾关系":
dict1[0].VOB = list1
case "间宾关系":
dict1[0].IOB = list1
case "前置宾语":
dict1[0].FOB = list1
case "兼语":
dict1[0].DBL = list1
case "定中关系":
dict1[0].ATT = list1
case "状中结构":
dict1[0].ADV = list1
case "动补结构":
dict1[0].CMP = list1
case "并列关系":
dict1[0].COO = list1
case "介宾关系":
dict1[0].POB = list1
case "左附加关系":
dict1[0].LAD = list1
case "右附加关系":
dict1[0].RAD = list1
case "独立结构":
dict1[0].IS = list1
case "核心关系":
dict1[0].HED = list1
}
// bb = make([]Hanlp, 0)
}
}
dict = append(dict, dict1...)
}
// fmt.Println(dict)
for i := 0; i < len(dict); i++ {
extract(hanlp, dict, i)
}
}
func extract(hanlp []HanlpJson, dict []Dict, i int) {
w := hanlp[i]
ww := dict[i]
//主谓宾关系:刘小绪生于四川
if len(ww.SBV) > 0 && len(ww.VOB) > 0 {
entity1 := ww.SBV[0].LEMMA
// 排除:刘小绪和李华是朋友
prep := ww.SBV[0]
prepIndex := prep.ID - 1
prepDict := dict[prepIndex] //这个写法注意,当做dict数组的索引和它ID是一致的
if len(prepDict.COO) > 0 {
relation := ww.VOB[0].LEMMA
entity2 := prepDict.COO[0].LEMMA
fmt.Println(entity1 + "," + relation + "," + entity2)
} else {
entity2 := ww.VOB[0].LEMMA
relation := w.LEMMA
fmt.Println(entity1 + "," + relation + "," + entity2)
}
}
// 动补结构:刘小绪洗干净了衣服
//"主谓关系"]
//"动宾关系"]
//"动补结构"]
if len(ww.SBV) > 0 && len(ww.VOB) > 0 && len(ww.CMP) > 0 {
entity1 := ww.SBV[0].LEMMA
complement := ww.CMP[0].LEMMA
entity2 := ww.VOB[0].LEMMA
if len(ww.RAD) > 0 { //右附加关系
subjoin := ww.RAD[0].LEMMA
relation := w.LEMMA + complement + subjoin
fmt.Println(entity1 + "," + relation + "," + entity2)
} else {
relation := w.LEMMA + complement
fmt.Println(entity1 + "," + relation + "," + entity2)
}
}
//定中关系
if len(ww.ATT) > 0 {
entity1 := ww.ATT[0].LEMMA
relation := w.LEMMA
for _, ii := range dict { //这里要用dict maps数组
//"主谓关系"]
//"动宾关系"]
if len(ii.SBV) > 0 && len(ii.VOB) > 0 {
if ii.SBV[0].LEMMA == relation {
entity2 := ii.VOB[0].LEMMA
fmt.Println(entity1 + "," + relation + "," + entity2)
}
}
}
}
// 状动结构:父亲非常喜欢跑步
// 非常 是 跑步的状语,关系应该为非常喜欢
//"主谓关系"]
//动宾关系"]
//"状中结构"]
if len(ww.SBV) > 0 && len(ww.VOB) > 0 && len(ww.ADV) > 0 {
entity1 := ww.SBV[0].LEMMA
adverbial := ww.ADV[0].LEMMA
entity2 := ww.VOB[0].LEMMA
relation := adverbial + w.LEMMA
fmt.Println(entity1 + "," + relation + "," + entity2)
}
// 状动补结构
//"主谓关系"]
//"动宾关系"]
//"状中结构"]
//"动补结构"]
if len(ww.SBV) > 0 && len(ww.VOB) > 0 && len(ww.ADV) > 0 && len(ww.CMP) > 0 {
entity1 := ww.SBV[0].LEMMA
adverbial := ww.ADV[0].LEMMA
complement := ww.CMP[0].LEMMA
entity2 := ww.VOB[0].LEMMA
relation := adverbial + w.LEMMA + complement
fmt.Println(entity1 + "," + relation + "," + entity2)
}
// 定语后置:父亲是来自肯尼亚的留学生
if w.DEPREL == "定中关系" {
if len(ww.VOB) > 0 {
entity1 := hanlp[w.HEAD.ID-1].LEMMA
relation := w.LEMMA
entity2 := ww.VOB[0].LEMMA
fmt.Println(entity1 + "," + relation + "," + entity2)
}
}
// 介宾关系:刘小绪就职于学校
// 于 和 学校 是介宾关系
//"主谓关系"]
//"动补结构"]
if len(ww.SBV) > 0 && len(ww.CMP) > 0 {
entity1 := ww.SBV[0].LEMMA
prep := ww.CMP[0] //maps["动补结构"][0]
prepIndex := prep.ID - 1
prepDict := dict[prepIndex] //这个写法注意,当做dict数组的索引和它ID是一致的
if len(prepDict.POB) > 0 {
entity2 := prepDict.POB[0].LEMMA //"介宾关系"][0]
relation := w.LEMMA + prep.LEMMA
fmt.Println(entity1 + "," + relation + "," + entity2)
}
}
// 宾语前置结构:海洋由水组成
if len(ww.FOB) > 0 {
entity2 := ww.FOB[0].LEMMA //maps["前置宾语"][0]
if len(ww.ADV) > 0 {
adverbial := ww.ADV[0] //maps["状中结构"][0]
prepIndex := adverbial.ID - 1
prepDict := dict[prepIndex]
if len(prepDict.POB) > 0 {
entity1 := prepDict.POB[0].LEMMA
relation := w.LEMMA
fmt.Println(entity1 + "," + relation + "," + entity2)
}
}
}
}