package pretreated import ( "fmt" "jy/clear" u "jy/util" qutil "qfw/util" "strings" "unicode/utf8" ) // 对table进行整体解析处理 func (tn *Table) AnalyTables(contactFormat *u.ContactFormat, isSite bool, codeSite string) []*Table { ts := tn.tableSubDemolitionTable() //分包,拆表 for n, table := range ts { //处理每个table if len(table.TRs) > 0 { //删除尾部空白行 table.deleteTrimTr() //table.Print() //校对表格 table.Adjust(isSite, codeSite) //查找表格的标签,table.Tag字段 table.FindTag() //分割表格 table.bSplit(n, ts, isSite, codeSite) table.TdContactFormat(contactFormat, isSite, codeSite) //contactFormat,处理采购单位,代理机构 //开始查找kv,核心模块,table.SortKV table.FindKV(isSite, codeSite) //table中抽取品牌,table.BrandData if u.IsBrandGoods { table.analyBrand() } //table中抽取单价和个数 if u.IsPriceNumber { //qutil.Debug("======================抽取price和number===========") table.extractPriceNumber() } res, _, _, _, _ := CheckCommon(table.Tag, "abandontable") if !res { //调试 //过滤、标准化、合并kv,table.StandKV,table.StandKVWeight table.KVFilter(isSite, codeSite) } //对有表头表格的处理 if table.Tag != "" && utf8.RuneCountInString(table.Tag) < 100 { co, m, b := CheckMultiPackage(table.Tag) //分包处理 if b { table.BPackage = b if len(table.BlockPackage.Map) == 0 { for _, av := range m { kv := u.NewJobKv() kv.KvTags = table.StandKV bd := u.PackageNumberConvert(av[0]) //切割文本分包 blockPackage := &u.BlockPackage{ Origin: av[0], Name: av[0], Text: co, TableKV: kv, Index: bd, } if bd != "" { table.BlockPackage.AddKey(bd, blockPackage) } else { table.BlockPackage.AddKey(av[0], blockPackage) } } } table.StandKV["项目名称"] = append(table.StandKV["项目名称"], &u.Tag{Key: "项目名称", Value: table.Tag, Weight: -300}) } } //判断是否是多包,并处理分包的//遍历td分块 table.CheckMultiPackageByTable(isSite, codeSite) //分包处理 //MergeKvTags(table.TableResult.KvTags, table.StandKV) } } return ts } // 查找每一个单元格的表头,调用FindNear func (table *Table) FindTdVal(td *TD, direct, vdirect int) (b bool) { if td.Val == "" || strings.TrimSpace(td.Val) == "" { return } near := table.FindNear(td, direct) if near != nil && near.BH && (near.KeyDirect == vdirect || near.KeyDirect == 0) && (near.KVDirect == direct || near.KVDirect == 0) && near.KVDirect < 3 { near.KVDirect = direct near.KeyDirect = vdirect td.KVDirect = direct key := repSpace.ReplaceAllString(near.Val, "") //临时去掉换行-进行判断 tmp_tdVal := strings.ReplaceAll(td.Val, "\n", "") if key == "名称" && near.StartCol == 0 && near.Rowspan > 0 { new_key := "" tr := table.TRs[:td.TR.RowPos] if len(tr) > len(tr)-1 && len(tr) > 0 { tds := tr[len(tr)-1].TDs if len(tds) > td.EndCol && tds != nil { td1 := tds[td.EndCol] if zbhxrSecondReg.MatchString(td1.Val) { new_key = td1.Val } } } if new_key == "" { for _, vn := range table.TRs[near.Rowspan-1].TDs { if strings.Contains(vn.Val, "代理") { key = "代理机构" break } else if strings.Contains(vn.Val, "招标") { key = "采购单位" break } else if strings.Contains(vn.Val, "中标") && utf8.RuneCountInString(tmp_tdVal) >= 4 { key = "中标单位" break } } } else { key = new_key } } else if zbhxrReg.MatchString(key) && findCandidate2.MatchString(tmp_tdVal) { new_key := "中标单位" tr_top := table.TRs[:td.TR.RowPos] if len(tr_top) > len(tr_top)-1 && len(tr_top) > 0 { //上临查询 tds := tr_top[len(tr_top)-1].TDs if len(tds) > td.ColPos && tds != nil && len(tds) == len(td.TR.TDs) { td1 := tds[td.ColPos] if zbhxrSortNameReg.MatchString(td1.Val) { new_key = td1.Val } else { if zbhxrSortReg_1.MatchString(td1.Val) { new_key = "中标候选人" + td1.Val } } } } if new_key == "中标单位" { //最左临查询 tr_left := table.TRs[:td.TR.RowPos+1] tds_left := tr_left[len(tr_left)-1].TDs if td.ColPos > 0 { td1 := tds_left[0] if zbhxrSortReg_2.MatchString(td1.Val) { //针对排名情况 new_key = "中标候选人第" + td1.Val + "名" } else { if zbhxrSortReg_1.MatchString(td1.Val) { new_key = "中标候选人" + td1.Val } } } } if new_key != "中标单位" { td.Val = tmp_tdVal } key = new_key } else if zbhxrReg.MatchString(key) && findCandidate3.MatchString(tmp_tdVal) { key = "中标单位名称" } else if key == "投标人名称" || key == "单位名称" { //左临上临-拼接 tmpnewnear := table.FindNear(near, 1) if tmpnewnear == nil { tmpnewnear = table.FindNear(near, 2) } if tmpnewnear != nil { if (table.Tag == "成交候选人" || table.Tag == "中标候选人") && zbhxrSortReg_1.MatchString(tmpnewnear.Val) { key = "中选候选人" + tmpnewnear.Val } else if table.Tag == "中标情况" { if tmpnewnear.MustBH || tmpnewnear.BH { if tmpnewnear.Val == "标段名称" && findCandidate2.MatchString(td.Val) { key = "中标单位名称" } } } else { if tmpnewnear.MustBH || tmpnewnear.BH { if tmpnewnear.Val == "中标候选人情况" && zbhxrSortReg_3.MatchString(td.Val) { key = "中标候选人第" + zbhxrSortReg_3.FindString(td.Val) + "名" } else if tmpnewnear.Val == "名次" || tmpnewnear.Val == "排名" || tmpnewnear.Val == "序号" || tmpnewnear.Val == "中标候选人排名" { if vv, ok := table.SortKV.Map[tmpnewnear.Val].(string); ok { if vv == "1" && findCandidate2.MatchString(td.Val) && key == "单位名称" { key = "中标单位名称" } } } else { key = tmpnewnear.Val + near.Val } } } } else { if table.Tag == "成交单位" && key == "单位名称" { key = "中标单位名称" } else if key == "单位名称" { tmpdirect := 2 if direct == 2 { tmpdirect = 1 } tmpnewnear = table.FindNear(td, tmpdirect) if tmpnewnear != nil { if tmpnewnear.Val == "中标人" { key = "中标单位名称" } } } } } else if key == "采购人(乙方)" || key == "采购人(乙方)" { if findCandidate2.MatchString(td.Val) { key = "中标单位" } } else if key == "企业名称" { if findCandidate2.MatchString(td.Val) && strings.Contains(qutil.ObjToString(table.Tag), "履约信息") { key = "中标单位" } } else if key == "发布部门" || key == "主体名称" { if findCandidate2.MatchString(td.Val) && strings.Contains(qutil.ObjToString(table.Tag), "履约信息") { key = "采购单位" } } else if key == "金额" { //父级表格 pre_near := table.FindNear(near, direct) if pre_near != nil { if pre_near.Val == "第一中标候选人" { key = pre_near.Val + key } } } else if key == "第一候选人" && qutil.Float64All(tmp_tdVal) > 0.0 { if tmp_near := table.FindNear(td, 2); tmp_near != nil { if winMoneyReg.MatchString(tmp_near.Val) { key = tmp_near.Val } } } else if key == "联系人" || key == "联系电话" { if table.Toptype_Old == "采购意向" { key = "采购" + key } } if near.Val == "" { key = fmtkey("k", near.TR.RowPos, near.ColPos) } val := table.SortKV.Map[key] //qutil.Debug("====================", "key:", key, "val:", val) bthiskey := false if val != nil { curpos := table.SortKV.Index[key] thistr := table.kTD[curpos] if thistr != near { if strings.TrimSpace(near.Val) == "名称" && near.TR != nil && len(near.TR.TDs) > 0 && near.ColPos-1 >= 0 { rv := near.TR.TDs[near.ColPos-1].Val if near.ColPos > 0 && (strings.Contains(rv, "招标") || strings.Contains(rv, "代理") || strings.Contains(rv, "采购") || strings.Contains(rv, "中标")) { near = near.TR.TDs[near.ColPos-1] } } else { bthiskey = true } } else { bthiskey = true } } bfind := false barr := false varrpos := -1 if bthiskey { //处理是数组值,且有合并行或合并列的情况 kvscope,对数组值的处理 pos := table.SortKV.Index[key] mval := table.kvscope[pos] bvalfind := false if direct == 1 { //kv是横向 L1: for k3, v3 := range mval { for _, v4 := range v3 { if v4.EndRow+1 == td.StartRow && v4.EndCol == td.EndCol { varrpos = k3 bvalfind = true break L1 } } } } else { //kv是纵向 L2: for k3, v3 := range mval { for _, v4 := range v3 { if v4.EndCol+1 == td.StartCol && v4.EndRow == td.EndRow { varrpos = k3 bvalfind = true break L2 } } } } if vals, ok := val.([]string); ok { if near.Val == "" { bn := false for _, vs := range vals { if vs != "" && NullTdReg.MatchString(vs) { bn = true } else { bn = false break } } if bn { near.Val = NullTxtBid key = NullTxtBid bfind = true } } if bvalfind && varrpos > -1 && len(vals) > varrpos { tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(td.Val, "")) if tmapval == "" { vals = append(vals, td.Val) // 累加 } else { vals = append(vals, tmapval) // 累加 } val = vals //vals[varrpos] = td.Val // += "__" + td.Val } else { //添加时候去除空值和nil newVals := []string{} for _, isval := range vals { if isval == "" { continue } newVals = append(newVals, isval) } //vals = append(vals, td.Val) if td.Val != "" { newVals = append(newVals, td.Val) } val = newVals varrpos = len(vals) - 1 } } else if vals, ok := val.(string); ok && vals != "" && td.Val != "" { tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(vals, "")) //已存在的kv tmapvaltd := strings.TrimSpace(cleardwReg.ReplaceAllString(td.Val, "")) if bvalfind { if key == "中标单位" { //不能覆盖--- } else { if tmapvaltd == "" { val = td.Val //vals + "__" + td.Val } else { val = tmapvaltd } } } else { if key == "中标单位" { //新增不能数组 } else { if zbhxrSortNameReg.MatchString(key) { //特殊~不构建数组 } else { tval := []string{} if tmapval == "" { tval = append(tval, vals) } else { tval = append(tval, tmapval) } if tmapvaltd == "" { tval = append(tval, td.Val) } else { tval = append(tval, tmapvaltd) } val = tval varrpos = 1 } } } } barr = true } else { if td.Val != "" { tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(td.Val, "")) if tmapval == "" { val = td.Val } else { val = tmapval } } else if len(near.SortKV.Map) == 1 && near.SortKV.Map[near.Val] != "" { val = near.SortKV.Map[near.Val] } } td.HeadTd = near if bfind { tkey := fmtkey("k", near.TR.RowPos, near.ColPos) table.SortKV.ReplaceKey(key, val, tkey) } else { if key == "单位名称" && len(near.TR.TDs) > 1 { if near.TR.TDs[0].Val != "序号" { key = near.TR.TDs[0].Val } } table.SortKV.AddKey(key, val) pos := table.SortKV.Index[key] if barr { mval := table.kvscope[pos] if mval != nil { tds := mval[varrpos] if tds != nil { tds = append(tds, td) } else { tds = []*TD{td} } if varrpos > -1 { mval[varrpos] = tds table.kvscope[pos] = mval } } } else { table.kvscope[pos] = map[int][]*TD{ 0: []*TD{td}, } table.kTD[pos] = near } } b = true } return } // 查找单元格的表头时,横向或纵向 func (table *Table) FindNear(td *TD, direct int) *TD { if direct == 1 && td.StartCol > 0 { //左临 tr := table.TRs[:td.TR.RowPos+1] for i := len(tr) - 1; i > -1; i-- { tds := tr[i].TDs for _, td1 := range tds { if td1.StartRow <= td.StartRow && td1.EndRow >= td.EndRow && td1.EndCol+1 == td.StartCol { //找到左临节点 if td1.BH || (zbhxrSortReg_1.MatchString(td1.Val) && (table.Tag == "成交候选人" || table.Tag == "中标候选人")) { return td1 } else { if td1.HeadTd != nil && td1.HeadTd.KVDirect == direct { return td1.HeadTd } } } } } } else if direct == 2 && td.StartRow > 0 { //上临 tr := table.TRs[:td.TR.RowPos] for i := len(tr) - 1; i > -1; i-- { tds := tr[i].TDs for it, td1 := range tds { if td1.StartCol <= td.StartCol && td1.EndCol >= td.EndCol && td1.EndRow+1 == td.StartRow { if td1.BH { //new_td := tds[td.ColPos] //列错落 //if td.ColPos!=it && new_td.BH { // return new_td //} return td1 } else if len(tr[i].TDs) == len(td.TR.TDs) && td1.HeadTd != nil && td1.HeadTd.KVDirect == direct { return td1.HeadTd } else if it > 0 && td1.Val == "" && td1.TR.TopTR == nil && len(td.TR.TDs)-(td.StartCol-1) > 0 && strings.Contains(td.TR.TDs[td.StartCol-1].Val, "中标候选人") { return tds[it-1] } else if td1.HeadTd != nil && td1.HeadTd.KVDirect == direct && td.Colspan == td1.Colspan && td.Rowspan == td.Rowspan { return td1.HeadTd } else { } } else if len(td.TR.TDs) == len(tds) && i == len(tr)-1 && len(tds) > td.ColPos && it == td.ColPos && td1.EndRow+1 == td.StartRow { new_td := tds[td.ColPos] if new_td.BH { return new_td } } } } } return nil } // 根据行号列号获取td对象 func (tn *Table) GetTdByRCNo(row, col int) *TD { for _, tr := range tn.TRs { for _, td := range tr.TDs { if td.StartCol <= col && td.EndCol >= col && td.StartRow <= row && td.EndRow >= row { return td } } } return nil } // 判断表格是否是分包 func (tn *Table) CheckMultiPackageByTable(isSite bool, codeSite string) (b bool, index []string) { pac := 0 //包的数量 val := 0 //分值 index = []string{} //存储分包,使用tbale.SortKV的key和value使用正则等处理对值进行判断 index_pos := []int{} //下标 //是数组且能找到标段之类的提示 //arr_count := 0 //计数table.SortKV的value是数组的数量,后面没用 key_index := -1 hasPkgTd := map[string]bool{} //初始化CheckMultiPackageByTable方法需要的数据 key_index, index, index_pos, val, pac, hasPkgTd = initCheckMultiPackageByTable(tn, key_index, index, index_pos, val, pac, hasPkgTd) //key是分包的情况 //记录key对应的值 commonKeyVals := map[string][]string{} //记录key出现的次数 keyExistsCount := map[string]int{} if pac > 1 { val = 10 } else { //查找标签 if TableMultiPackageReg_4.MatchString(tn.Tag) { val += 4 } else if TableMultiPackageReg_2.MatchString(tn.Tag) { val += 4 } //根据table.SortKV的key判断是否分包,如果没有再根据value判断 val, index, index_pos = foundPacBySortKV(tn, val, index, index_pos, &keyExistsCount, &commonKeyVals, key_index, hasPkgTd) } // u.Debug(index) //过滤重复及标准化! standIndex := []string{} standIndex_pos := []int{} oldIndex := []string{} //存放包的原始值 brepeat := map[string]bool{} for k, v := range index { v = u.PackageNumberConvert(v) if !brepeat[v] { brepeat[v] = true standIndex = append(standIndex, v) standIndex_pos = append(standIndex_pos, index_pos[k]) oldIndex = append(oldIndex, index[k]) } } index = standIndex //有一个以上的包,并且相同的key出现一次以上,认为这个key是属于包里面的 if len(commonKeyVals) > 0 { for k, v := range commonKeyVals { if len(index) > 1 && keyExistsCount[k] < 2 { continue } tn.SortKV.AddKey(k, v) } } // isGoonNext := false if val > 4 && len(brepeat) > 0 { b = true //多包解析 if b { tn.BPackage = true //pnum := len(index) //根据数组index分包长度添加table.BlockPackage子包数组 for nk, v := range index { if tn.BlockPackage.Map[v] == nil { kv := u.NewJobKv() for tnk, tnv := range tn.StandKV { if nk >= len(tnv) { continue } else if len(index) == len(tnv) { if tnk == "预算" && isUnRealBudgetBp(tnv) { continue } if tnk == "预算" && codeSite == "ha_zmdszfcgw_cgxx" && len(tnv) > 1 { isEqErr, budget_v := false, "" for bk, bv := range tnv { if bk == 0 { budget_v = bv.Value } else { if budget_v != bv.Value { isEqErr = true break } } } if isEqErr { kv.KvTags[tnk] = append(kv.KvTags[tnk], tnv[nk]) } } else { kv.KvTags[tnk] = append(kv.KvTags[tnk], tnv[nk]) } } } //kv.KvTags = tn.StandKV bp := &u.BlockPackage{} bp.Index = v //序号 (转换后编号,只有数字或字母) bp.Origin = oldIndex[nk] //包的原始值 bp.TableKV = kv //table kv (分出的对应的KV值) bp.Name = v if bp.TableKV != nil && bp.TableKV.KvTags != nil && len(bp.TableKV.KvTags) > 0 { for kc, cv := range bp.TableKV.KvTags { if kc == "预算" && bp.Budget <= 0 { moneys := clear.ObjToMoney([]interface{}{cv[0].Value, ""}) if len(moneys) > 0 { if vf, ok := moneys[0].(float64); ok { bp.Budget = vf bp.IsTrueBudget = moneys[len(moneys)-1].(bool) } else if vi, ok := moneys[0].(int); ok { bp.Budget = float64(vi) bp.IsTrueBudget = moneys[len(moneys)-1].(bool) } } } else if kc == "中标金额" && bp.Bidamount <= 0 { moneys := clear.ObjToMoney([]interface{}{cv[0].Value, ""}) if len(moneys) > 0 { if vf, ok := moneys[0].(float64); ok { bp.Bidamount = vf bp.IsTrueBidamount = moneys[len(moneys)-1].(bool) } else if vi, ok := moneys[0].(int); ok { bp.Bidamount = float64(vi) bp.IsTrueBidamount = moneys[len(moneys)-1].(bool) } } } else if kc == "中标单位" && bp.Winner == "" { bp.Winner = cv[0].Value } //拼接内容 if !excludeKey.MatchString(kc) { bp.Text += fmt.Sprintf("%v:%v\n", kc, cv[0].Value) } } } else { //新增 - 特殊情况 - 查找sortKV - 预算 - 中标金额 - 中标单位 for k, v := range tn.SortKV.Map { //kt := u.GetTags(k, isSite, codeSite) if budgetSortKVReg.MatchString(k) { if vs, ok := v.([]string); ok { if len(index) == len(vs) { moneys := clear.ObjToMoney([]interface{}{vs[nk], ""}) if len(moneys) > 0 { if vf, ok := moneys[0].(float64); ok { if !strings.Contains(vs[nk], "万") && strings.Contains(k, "万") { vf = 10000.0 * vf } bp.Budget = vf bp.IsTrueBudget = moneys[len(moneys)-1].(bool) } else if vi, ok := moneys[0].(int); ok { if !strings.Contains(vs[nk], "万") && strings.Contains(k, "万") { vi = 10000 * vi } bp.Budget = float64(vi) bp.IsTrueBudget = moneys[len(moneys)-1].(bool) } } } } } if bidamountSortKVReg.MatchString(k) { if vs, ok := v.([]string); ok { if len(index) == len(vs) { moneys := clear.ObjToMoney([]interface{}{vs[nk], ""}) if len(moneys) > 0 { if vf, ok := moneys[0].(float64); ok { if !strings.Contains(vs[nk], "万") && strings.Contains(k, "万") { vf = 10000.0 * vf } bp.Bidamount = vf bp.IsTrueBidamount = moneys[len(moneys)-1].(bool) } else if vi, ok := moneys[0].(int); ok { if !strings.Contains(vs[nk], "万") && strings.Contains(k, "万") { vi = 10000.0 * vi } bp.Bidamount = float64(vi) bp.IsTrueBidamount = moneys[len(moneys)-1].(bool) } } } } } if winnerSortKVReg.MatchString(k) { if vs, ok := v.([]string); ok { if len(index) == len(vs) { bp.Winner = vs[nk] } } } } } tn.BlockPackage.AddKey(v, bp) //table子包数组 } } isGoonNext = tn.manyPackageProcessByIndex(index, standIndex_pos, isSite, codeSite) //多包处理,处理不同情况下的分包 } } else { isGoonNext = true } if isGoonNext { //没有处理成数组的情况下,继续调用正文查找分包的方法 tn.isGoonNext(isSite, codeSite) } //查找分包中的中标人排序-分包找候选人 if tn.BlockPackage != nil && tn.BlockPackage.Keys != nil && len(tn.BlockPackage.Keys) > 0 { for _, v := range tn.BlockPackage.Keys { vv, ok := tn.BlockPackage.Map[v].(*u.BlockPackage) if ok && (vv.WinnerOrder == nil || len(vv.WinnerOrder) == 0) { vv.WinnerOrder = winnerOrderEntity.Find(vv.Text, true, 2, isSite, codeSite) } //if ok && (vv.WinnerOrder == nil || len(vv.WinnerOrder) == 0) && (tn.WinnerOrder == nil || len(tn.WinnerOrder) == 0) { // vv.WinnerOrder = tn.WinnerOrder //} } } return } // 多包处理,处理不同情况下的分包 func (tn *Table) manyPackageProcessByIndex(index []string, standIndex_pos []int, isSite bool, codeSite string) (isGoonNext bool) { if len(index) == 1 { //是一个的情况 if len(tn.SortKV.Keys) < 10 && tn.ColNum < 10 && tn.RowNum < 4 { //table带排序的KV值小于10并且小于10列和小于4行 beq := true for _, v2 := range tn.SortKV.Keys { if _, ok := tn.SortKV.Map[v2].(string); !ok { beq = false break } } if beq { //统一处理为数组 td := tn.GetTdByRCNo(tn.RowNum-1, 0) if !td.BH && FindVal2_1.MatchString(td.Val) { for _, v2 := range tn.SortKV.Keys { tn.SortKV.AddKey(v2, []string{tn.SortKV.Map[v2].(string)}) } } else { //没有处理成数组的情况下,继续调用正文查找分包的方法 isGoonNext = true } } } } for _, k1 := range tn.SortKV.Keys { v1 := tn.SortKV.Map[k1] var v1_arr []string if vtmpv1, ok := v1.(string); ok { v1_arr = PreCon4.FindAllString(qutil.ObjToString(vtmpv1), -1) if len(v1_arr) > 0 { if dw := Precon4dw.FindString(vtmpv1); dw != "" { for i, v := range v1_arr { v1_arr[i] = v + dw } } } } else if vtmpv1s, ok := v1.([]string); ok { v1_arr = vtmpv1s } if len(v1_arr) > 0 && len(v1_arr) <= len(index) { //table.SortKV.Map.value数组小于等于分包index for k, v := range v1_arr { tn.assemblePackage(k1, v, index[k], isSite, codeSite) //组装解析到的分包 } } } return isGoonNext } // 没有处理成数组的情况下,继续调用正文查找分包的方法 func (tn *Table) isGoonNext(isSite bool, codeSite string) { blockPackage := map[string]*u.BlockPackage{} for _, k := range tn.SortKV.Keys { if excludeKey.MatchString(k) || strings.Contains(k, "批复") || excludeKey3.MatchString(k) { continue } str := "" //拼装为冒号kv v := tn.SortKV.Map[k] nk := regReplAllSpace.ReplaceAllString(k, "") if vs, ok := v.([]string); ok { str += fmt.Sprintf("%s:%s\n", nk, strings.Join(vs, " ")) } else { str += fmt.Sprintf("%s:%s\n", nk, v) } if excludeKey2.MatchString(str) { continue } b, _ := divisionPackageChild(&blockPackage, str, tn.Tag, false, false, isSite, codeSite) //分块之后分包 if b && len(blockPackage) > 0 { tn.BPackage = true for mk, mv := range blockPackage { if tn.BlockPackage.Map[mk] == nil { tn.BlockPackage.AddKey(mk, mv) } else { bp := tn.BlockPackage.Map[mk].(*u.BlockPackage) if bp.TableKV == nil { bp.TableKV = u.NewJobKv() } if bp.SpaceKV == nil { bp.SpaceKV = u.NewJobKv() } for k2, v2 := range mv.ColonKV.KvTags { for _, v2v := range v2 { isExists := false for _, v2vv := range bp.TableKV.KvTags[k2] { if v2v.Value == v2vv.Value { isExists = true break } } if !isExists { bp.TableKV.KvTags[k2] = append(bp.TableKV.KvTags[k2], v2v) bp.Text += fmt.Sprintf("%v:%v\n", k2, v2) } } } for k2, v2 := range mv.SpaceKV.KvTags { for _, v2v := range v2 { isExists := false for _, v2vv := range bp.SpaceKV.KvTags[k2] { if v2v.Value == v2vv.Value { isExists = true break } } if !isExists { bp.SpaceKV.KvTags[k2] = append(bp.SpaceKV.KvTags[k2], v2v) bp.Text += fmt.Sprintf("%v:%v\n", k2, v2) } } } } } tn.BPackage = true tn.SortKV.RemoveKey(k) } } } // 根据table.SortKV的key判断是否分包,如果没有再根据value判断 func foundPacBySortKV(tn *Table, val int, index []string, index_pos []int, keyExistsCount *map[string]int, commonKeyVals *map[string][]string, key_index int, hasPkgTd map[string]bool) (rval int, rindex []string, rindex_pos []int) { keyIsPkg := false for in, k := range tn.SortKV.Keys { if excludeKey.MatchString(BracketsTextReg.ReplaceAllString(k, "")) || excludeKey3.MatchString(k) || regFJWarap.MatchString(k) || regAZWarap.MatchString(k) { //判断分包前排除 continue } v := tn.SortKV.Map[k] //key是分包的情况 if ismatch := FindVal_1.MatchString(k); keyIsPkg || ismatch { if ismatch { keyIsPkg = true val += 4 pkgFlag := FindVal_1.FindString(k) //对值进行分包判断 k = strings.Replace(k, pkgFlag, "", -1) index = append(index, pkgFlag) index_pos = append(index_pos, len(index)) val += 1 //pac++ } else { k = strings.TrimRight(k, "_") } (*keyExistsCount)[k] = (*keyExistsCount)[k] + 1 (*commonKeyVals)[k] = append((*commonKeyVals)[k], qutil.ObjToString(v)) } else if k1 := FilterKey_2.ReplaceAllString(k, ""); FindKey_2.MatchString(k1) { val += 4 //value数组分包 if vs, bvs1 := v.([]string); bvs1 { L: for in2, v1 := range vs { if len([]rune(v1)) < 20 && !moneyNum.MatchString(v1) && FindVal2_1.MatchString(v1) { for _, serial := range tn.TableResult.RuleBlock.TitleRegs { if serial.MatchString(v1) { break L } } if key_index == -1 { key_index = in } else if key_index != in { break } index = append(index, v1) index_pos = append(index_pos, in2) val += 1 //pac++ } } } else if v1, ok := v.(string); ok && !hasPkgTd[k] { //value字符串分包 v1 = replPkgConfusion(v1) //替换分包中混淆的词 for _, v2 := range strings.Split(v1, "/") { if len([]rune(v2)) < 20 && !moneyNum.MatchString(v2) && FindVal2_1.MatchString(v2) { key_index = in index = append(index, v1) index_pos = append(index_pos, 0) val += 1 //pac++ underline := "" for { underline += "_" if tn.SortKV.Map[k+underline] == nil { break } else if v3, v2_ok := tn.SortKV.Map[k+underline].(string); v2_ok && v3 != "" { index = append(index, v3) index_pos = append(index_pos, 1) } else if v3, v2_ok := tn.SortKV.Map[k+underline].([]string); v2_ok { for v2_k, v2_v := range v3 { index = append(index, v2_v) index_pos = append(index_pos, v2_k+1) } } } break } } } if k1 == "标段" && len(index) == 0 { continue } else { break } } } return val, index, index_pos } // 初始化CheckMultiPackageByTable方法需要的数据 func initCheckMultiPackageByTable(tn *Table, key_index int, index []string, index_pos []int, val int, pac int, hasPkgTd map[string]bool) (rkey_index int, rindex []string, rindex_pos []int, rval int, rpac int, rhasPkgTd map[string]bool) { for in, k := range tn.SortKV.Keys { //涉及包号|包件号?|项目标号|规格|型号|招标范围|业绩|废标)|(^编号$)|([^包段标]编号)就跳过 if excludeKey.MatchString(BracketsTextReg.ReplaceAllString(k, "")) || excludeKey3.MatchString(k) || strings.Contains(k, "批复") { continue } v := tn.SortKV.Map[k] if vs, bvs := v.([]string); bvs { //arr_count++ haspkgs := []string{} for in2, v1 := range vs { v1 = replPkgConfusion(v1) //替换分包中混淆的词 if len([]rune(v1)) < 30 && !moneyNum.MatchString(v1) && FindVal_1.MatchString(v1) { if key_index == -1 { key_index = in } else if key_index != in { break } index = append(index, FindVal_1.FindString(v1)) index_pos = append(index_pos, in2) val += 1 pac++ } else if FindKey_3.MatchString(k) { //5db2a101a5cb26b9b73054ac index = append(index, v1) index_pos = append(index_pos, in2) val += 1 pac++ } else { if ok, v1new := isHasOnePkgAndNoKv(v1); ok { //td的值里面有一个包,并且没有冒号kv haspkgs = append(haspkgs, v1new) } } } /*处理这种情况: