Jelajahi Sumber

table分包

fengweiqiang 6 tahun lalu
induk
melakukan
6a72868b69
1 mengubah file dengan 362 tambahan dan 305 penghapusan
  1. 362 305
      src/jy/pretreated/analytable.go

+ 362 - 305
src/jy/pretreated/analytable.go

@@ -207,7 +207,7 @@ func (table *Table) KVFilter() {
 	if !winnertag {
 		winnertag = iswinnertabletag.MatchString(table.Tag) && !nswinnertabletag.MatchString(table.TableResult.BlockTag) //块标签
 	}
-	table.analyTdKV()
+	table.analyTdKV() //1.td元素有内嵌kv,遍历放入table的Kv中2.td有子表格的处理,中标候选人排序
 	as := NewSortMap()
 	//表格描述处理,对成交结果的处理
 	for _, k := range table.SortKV.Keys {
@@ -1397,16 +1397,7 @@ func (table *Table) FindKV() {
 		sort := 1
 		//开始抽取
 		for _, tr := range table.TRs {
-			if len(tr.TDs) == 1 {
-				bcon = false
-				td := tr.TDs[0]
-				if td.StartCol == 0 && td.EndCol+1 == table.ColNum && len([]rune(td.Val)) > 4 && len([]rune(td.Val)) < 50 {
-					res, _, _, _, _ := CheckCommon(td.Val, "abandontable")
-					if res { //以下内容丢弃
-						bcon = true
-					}
-				}
-			}
+			bcon = trSingleColumn(tr, bcon, table) //tr单列,是否丢弃内容
 			if bcon {
 				continue
 			}
@@ -1443,6 +1434,11 @@ func (table *Table) FindKV() {
 								sort++
 								bodirect = bo
 							}
+							if len(td.SortKV.Map) > 0 {
+								for tdk, tdv := range td.SortKV.Map {
+									table.SortKV.AddKey(tdk, tdv)
+								}
+							}
 						}
 					}
 					//fmt.Println("td:", td.Val, td.BH, td.HeadTd, td.KVDirect)
@@ -1451,20 +1447,7 @@ func (table *Table) FindKV() {
 		}
 		//qutil.Debug("FindKV", table.SortKV.Map)
 	} else if len(table.TRs) > 0 { //没有表头的表格处理,默认纵向吧
-		res := make([][]string, len(table.TRs[0].TDs))
-		for n, _ := range res {
-			res[n] = []string{}
-		}
-		for _, tr := range table.TRs {
-			for n, td := range table.TRs[0].TDs { //第一行的所有td
-				td1 := table.GetTdByRCNo(tr.TDs[0].StartRow, td.StartCol)
-				if td1 != nil {
-					res[n] = append(res[n], td1.Val)
-				} else {
-					res[n] = append(res[n], "")
-				}
-			}
-		}
+		res := initLongitudinalData(table) //拼装纵向数组
 		//再拆值,类似http://www.ggzy.hi.gov.cn/cgzbgg/16553.jhtml第二列,有多个值
 		nmapkeys := []int{}
 		nmap := map[int][]*u.Kv{}
@@ -1473,7 +1456,7 @@ func (table *Table) FindKV() {
 			for n, r := range r1 {
 				if len([]rune(r)) < 60 { // 长度小于60才去分
 					//res1, _ := GetKVAll(r, "", nil)
-					res1, _ := colonkvEntity.entrance(r, "", 2)
+					res1, _ := colonkvEntity.entrance(r, "", 2) //冒号kv
 					if res1 != nil {
 						nmap[n] = res1
 						nmapkeys = append(nmapkeys, n)
@@ -1545,6 +1528,40 @@ func (table *Table) FindKV() {
 	//qutil.Debug("FindKV", table.SortKV.Map)
 }
 
+//初始化组装纵向数据
+func initLongitudinalData(table *Table) [][]string {
+	res := make([][]string, len(table.TRs[0].TDs)) //创建table第一行的列数长度
+	for n, _ := range res {
+		res[n] = []string{}
+	}
+	for _, tr := range table.TRs {
+		for n, td := range table.TRs[0].TDs { //第一行的所有td
+			td1 := table.GetTdByRCNo(tr.TDs[0].StartRow, td.StartCol) //根据行号列号获取td对象
+			if td1 != nil {
+				res[n] = append(res[n], td1.Val)
+			} else {
+				res[n] = append(res[n], "")
+			}
+		}
+	}
+	return res
+}
+
+//tr单列,是否丢弃内容
+func trSingleColumn(tr *TR, bcon bool, table *Table) bool {
+	if len(tr.TDs) == 1 {
+		bcon = false
+		td := tr.TDs[0]
+		if td.StartCol == 0 && td.EndCol+1 == table.ColNum && len([]rune(td.Val)) > 4 && len([]rune(td.Val)) < 50 {
+			res, _, _, _, _ := CheckCommon(td.Val, "abandontable")
+			if res { //以下内容丢弃
+				bcon = true
+			}
+		}
+	}
+	return bcon
+}
+
 //获取中标人顺序
 //direct 0默认 1横向 2纵向
 func GetBidOrder(td *TD, direct, n int) (d int, res bool) {
@@ -1758,7 +1775,11 @@ func (table *Table) FindTdVal(td *TD, direct, vdirect int) (b bool) {
 			}
 			barr = true
 		} else {
-			val = td.Val
+			if td.Val != "" {
+				val = td.Val
+			} else if len(near.SortKV.Map) == 1 && near.SortKV.Map[near.Val] != "" {
+				val = near.SortKV.Map[near.Val]
+			}
 		}
 		td.HeadTd = near
 		if bfind {
@@ -1852,80 +1873,14 @@ func (tn *Table) GetTdByRCNo(row, col int) *TD {
 func (tn *Table) CheckMultiPackageByTable() (b bool, index []string) {
 	pac := 0
 	val := 0
-	index = []string{}
+	index = []string{} //初始化返回值index
 	index_pos := []int{}
 	//是数组且能找到标段之类的提示
-	arr_count := 0
+	//arr_count := 0 //计数table.SortKV的value是数组的数量,后面没用
 	key_index := -1
 	hasPkgTd := map[string]bool{}
-	for in, k := range tn.SortKV.Keys {
-		//涉及包号|包件号?|项目标号|规格|型号|招标范围|业绩|废标)|(^编号$)|([^包段标]编号)就跳过
-		if excludeKey.MatchString(BracketsTextReg.ReplaceAllString(k, "")) {
-			continue
-		}
-		v := tn.SortKV.Map[k]
-		vs, bvs := v.([]string)
-		if bvs {
-			arr_count++
-			haspkgs := []string{}
-			for in2, v1 := range vs {
-				v1 = replPkgConfusion(v1)
-				if len([]rune(v1)) < 8 && !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 ok, v1new := isHasOnePkgAndNoKv(v1); ok {
-						haspkgs = append(haspkgs, v1new)
-					}
-				}
-			}
-			/*处理这种情况:
-			<tr><td>包一:xxxxxxxxx</td></tr>
-			<tr><td>包二:xxxxxxxxx</td></tr>
-			*/
-			if len(index) == 0 && len(haspkgs) > 0 && len(haspkgs) == len(vs) {
-				for in2, v1 := range haspkgs {
-					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 {
-			v1 = replPkgConfusion(v1) //替换分包中混淆的词
-			if len([]rune(v1)) < 8 && !moneyNum.MatchString(v1) && FindVal_1.MatchString(v1) {
-				key_index = in
-				index = append(index, FindVal_1.FindString(v1))
-				index_pos = append(index_pos, 0)
-				val += 1
-				pac++
-			} else if getTd := tn.GetTdByRCNo(0, tn.SortKV.Index[k]); getTd != nil && getTd.KVDirect == 2 {
-				/*处理这种情况:
-				<tr><td>包一:xxxxxxxxx</td></tr>
-				*/
-				if ok, v1new := isHasOnePkgAndNoKv(v1); ok {
-					hasPkgTd[k] = true
-					key_index = in
-					index = append(index, v1new)
-					index_pos = append(index_pos, 0)
-					val += 1
-					pac++
-				}
-			}
-		}
-	}
+	//初始化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{}
@@ -1940,81 +1895,8 @@ func (tn *Table) CheckMultiPackageByTable() (b bool, index []string) {
 		} else if TableMultiPackageReg_2.MatchString(tn.Tag) {
 			val += 4
 		}
-		keyIsPkg := false
-		for in, k := range tn.SortKV.Keys {
-			if excludeKey.MatchString(BracketsTextReg.ReplaceAllString(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
-				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] {
-					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
-						}
-					}
-				}
-				break
-			}
-		}
+		//根据table.SortKV的key判断是否分包,如果没有再根据value判断
+		val, index, index_pos = foundPacBySortKV(tn, val, index, index_pos, pac, &keyExistsCount, &commonKeyVals, key_index, hasPkgTd)
 	}
 	//	u.Debug(index)
 	//过滤重复及标准化!
@@ -2054,7 +1936,7 @@ func (tn *Table) CheckMultiPackageByTable() (b bool, index []string) {
 					bp.Index = v
 					bp.Origin = oldIndex[nk]
 					bp.TableKV = u.NewJobKv()
-					tn.BlockPackage.AddKey(v, bp)
+					tn.BlockPackage.AddKey(v, bp)//table子包数组
 				}
 			}
 			if len(index) == 1 { //是一个的情况
@@ -2132,7 +2014,7 @@ func (tn *Table) CheckMultiPackageByTable() (b bool, index []string) {
 				} else if val, bvs := v1.(string); bvs && len(index) == 1 {
 					//删除子包的kv
 					k1tags, _, _, _, _ := CommonDataAnaly(k1, "", "", val)
-					if !(len(k1tags) > 0 && regexp.MustCompile("^(项目|开标|采购单位|招标机构)").MatchString(k1tags[0])) { //(k1tags[0].Value == "采购单位" || k1tags[0].Value == "项目编号")) {
+					if (len(k1tags) > 0 && regexp.MustCompile("^(项目|开标|采购单位|招标机构)").MatchString(k1tags[0])) { //(k1tags[0].Value == "采购单位" || k1tags[0].Value == "项目编号")) {
 						//log.Println("remove", k1, val)
 						tn.assemblePackage(k1, val, index[0])
 						tn.SortKV.RemoveKey(k1)
@@ -2202,6 +2084,159 @@ func (tn *Table) CheckMultiPackageByTable() (b bool, index []string) {
 	}
 	return
 }
+//根据table.SortKV的key判断是否分包,如果没有再根据value判断
+func foundPacBySortKV(tn *Table, val int, index []string, index_pos []int, pac 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, "")) { //判断分包前排除
+			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
+					}
+				}
+			}
+			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, "")) {
+			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)) < 8 && !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 ok, v1new := isHasOnePkgAndNoKv(v1); ok { //td的值里面有一个包,并且没有冒号kv
+						haspkgs = append(haspkgs, v1new)
+					}
+				}
+			}
+			/*处理这种情况:
+			<tr><td>包一:xxxxxxxxx</td></tr>
+			<tr><td>包二:xxxxxxxxx</td></tr>
+			*/
+			if len(index) == 0 && len(haspkgs) > 0 && len(haspkgs) == len(vs) {
+				for in2, v1 := range haspkgs {
+					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 {
+			v1 = replPkgConfusion(v1) //替换分包中混淆的词
+			if len([]rune(v1)) < 8 && !moneyNum.MatchString(v1) && FindVal_1.MatchString(v1) {
+				key_index = in
+				index = append(index, FindVal_1.FindString(v1))
+				index_pos = append(index_pos, 0)
+				val += 1
+				pac++
+			} else if getTd := tn.GetTdByRCNo(0, tn.SortKV.Index[k]); getTd != nil && getTd.KVDirect == 2 {
+				/*处理这种情况:
+				<tr><td>包一:xxxxxxxxx</td></tr>
+				*/
+				if ok, v1new := isHasOnePkgAndNoKv(v1); ok {
+					hasPkgTd[k] = true
+					key_index = in
+					index = append(index, v1new)
+					index_pos = append(index_pos, 0)
+					val += 1
+					pac++
+				}
+			}
+		}
+	}
+	return key_index, index, index_pos, val, pac, hasPkgTd
+}
 
 //组装解析到的分包
 func (tn *Table) assemblePackage(k1, v1, key string) {
@@ -2844,6 +2879,7 @@ func (tn *Table) tdkv(td *TD) []*u.Kv {
 	return thisTdKvs
 }
 
+//table中抽取品牌,table.BrandData
 func (table *Table) analyBrand() {
 	//5c2d8c05a5cb26b9b782572b
 	//产品名称 品牌 规格 单价 单位 数量  小计 质保期
@@ -2851,75 +2887,17 @@ func (table *Table) analyBrand() {
 	lineMap := make(map[string]*SortMap)
 	brandRule := u.BrandRules
 	//初始化lineMapArr,lineMap;
-	initLineMapLineMapArr(table, lineMapArr, lineMap) //处理数组数据后,匹配必须title和替换要保存的title
+	lineMapArr, lineMap = initLineMapLineMapArr(table) //处理数组数据后,匹配必须title和替换要保存的title
 	//qutil.Debug("lineMapArr----", len(lineMapArr))
 	if len(lineMapArr) > 0 {
 		for _, aMap := range lineMapArr {
-			maxNum := 0
+			maxNum := 0    //记录最大长度
 			arrcount1 := 0 //记录key是否存在必须title(数组数据)
 			arrcount2 := 0
 			ka := make(map[string][]string) //最终存储数据
 			//qutil.Debug("aMap.Keys----", aMap.Keys)
-			for _, k0 := range aMap.Keys {
-				match := false //记录must是否匹配到
-				v0 := aMap.Map[k0].([]string)
-				//匹配必须title
-				for nameM, r := range brandRule["must"] {
-					if convert(k0, r) { //匹配成功
-						v0tmp1 := v0
-						match = true
-						if len(ka[nameM]) != 0 && strings.Contains(k0, "描述") { //防止k0匹配到多次 和特殊情况 物料名称 物料描述同时出现
-							continue
-						}
-						if nameM == "itemname" || nameM == "modal" {
-							hasGoods(table, v0...) //判断itemname和modal中有没有商品
-							if nameM == "itemname" {
-								v0tmp1 = filterItem(v0...) //过滤itemname
-							}
-						}
-						if nameM == "brandname" || nameM == "modal" {
-							if len(ka["brandname"]) == 0 {
-								brand, allNull := hasBrand(table, v0...)
-								if !allNull {
-									ka["brandname"] = brand
-								}
-							}
-						}
-						//unitprice
-						if nameM == "unitprice" { //处理金额
-							v0tmp1 = dealPrice(k0, v0...)
-						}
-						if nameM != "brandname" && len(ka[nameM]) == 0 {
-							ka[nameM] = v0tmp1
-						}
-						arrcount1++
-					}
-				}
-				//替换其它要保存字段
-				if !match { //must未匹配,匹配replace
-					for nameR, r := range brandRule["replace"] {
-						if convert(k0, r) { //匹配成功
-							v0tmp2 := v0
-							//totalprice
-							if nameR == "totalprice" { //处理金额
-								v0tmp2 = dealPrice(k0, v0...)
-							}
-							//number
-							if nameR == "number" { //处理数量
-								uname0 := []string{}
-								v0tmp2, uname0 = dealNumber(v0...)
-								if len(ka["unitname"]) == 0 && len(uname0) != 0 {
-									ka["unitname"] = uname0
-								}
-							}
-							if len(v0tmp2) > 0 {
-								ka[nameR] = v0tmp2
-							}
-							arrcount2++
-						}
-					}
-				}
-			}
+			//匹配商品规则
+			arrcount1, arrcount2, ka = table.matchMapArrBrandRule(aMap, brandRule, ka, arrcount1, arrcount2)
 			//找最终存储数据的最小len(arr)
 			//			for _, vf := range ka {
 			//				//找最短的数组
@@ -2935,9 +2913,13 @@ func (table *Table) analyBrand() {
 					maxNum = lenVal
 				}
 			}
+			//table.BrandData商品存储
 			finishKa := make(map[string][]string)
 			for vf2K, vf2 := range ka {
 				if len(vf2) < maxNum {
+					if vf2K == "unitprice" { //价格的当前总数比最大的总数小就跳过,可能是总价格而不是单个的价格
+						continue
+					}
 					lenMv := maxNum - len(vf2)
 					for i := 0; i < lenMv; i++ {
 						vf2 = append(vf2, "")
@@ -2952,7 +2934,7 @@ func (table *Table) analyBrand() {
 					delete(finishKa, "unitprice")
 				}
 				finishData := dealArrData(maxNum, finishKa)
-				table.BrandData = append(table.BrandData, finishData) //修改了table.BrandData
+				table.BrandData = append(table.BrandData, finishData) //存储了table.BrandData
 			}
 		}
 	}
@@ -2964,73 +2946,8 @@ func (table *Table) analyBrand() {
 			strcount2 := 0
 			endStrMap := make(map[string]string)
 			//qutil.Debug(k, "aMap.Keys----", sMap.Keys)
-			for _, k1 := range sMap.Keys {
-				match := false //记录must是否匹配到
-				v1 := qutil.ObjToString(sMap.Map[k1])
-				//	for k1, v1 := range sMap {
-				//qutil.Debug(k1, "++++++++++", v1)
-				if v1 == "" {
-					continue
-				}
-				//匹配必须title
-				for nameM, r := range brandRule["must"] {
-					if convert(k1, r) { //匹配成功
-						v1tmp1 := v1
-						match = true
-						if nameM == "itemname" || nameM == "modal" { //特殊处理itemname
-							hasGoods(table, v1)
-							if nameM == "itemname" {
-								v1tmp1 = filterItem(v1)[0] //过滤itemname
-								if v1tmp1 == "" {
-									break
-								}
-							}
-						}
-						if nameM == "brandname" || nameM == "modal" { //特殊处理brandname
-							if endStrMap["brandname"] == "" {
-								brand, allNull := hasBrand(table, v1)
-								if !allNull {
-									endStrMap["brandname"] = brand[0]
-								}
-							}
-						}
-						//unitprice
-						if nameM == "unitprice" { //处理金额
-							v1tmp1 = dealPrice(k1, v1)[0]
-						}
-						if nameM != "brandname" && endStrMap[nameM] == "" {
-							endStrMap[nameM] = v1tmp1
-						}
-						strcount1++
-					}
-				}
-				//替换其它要保存字段
-				if !match {
-					for nameR, r := range brandRule["replace"] {
-						if convert(k1, r) { //匹配成功
-							v1tmp2 := v1
-							//totalprice
-							if nameR == "totalprice" { //处理金额
-								v1tmp2 = dealPrice(k1, v1)[0]
-							}
-							//number
-							if nameR == "number" { //处理数量
-								varr1, uname1 := dealNumber(v1)
-								v1tmp2 = varr1[0]
-								//从number中获取到的单位
-								if endStrMap["unitname"] == "" && uname1[0] != "" {
-									endStrMap["unitname"] = uname1[0]
-								}
-							}
-							if v1tmp2 != "" {
-								endStrMap[nameR] = v1tmp2
-							}
-							strcount2++
-						}
-					}
-				}
-				//}
-			}
+			//匹配商品规则
+			strcount1, strcount2, endStrMap = table.matchMapBrandRule(sMap, brandRule, endStrMap, strcount1, strcount2)
 			//原始字符串数据处理
 			hasKey(table, strcount1) //是否匹配到table中的标题
 			//qutil.Debug("endStrMap----", endStrMap)
@@ -3047,8 +2964,147 @@ func (table *Table) analyBrand() {
 	}
 }
 
+//字符串匹配商品规则
+func (table *Table) matchMapBrandRule(sMap *SortMap, brandRule map[string]map[string]string, endStrMap map[string]string, strcount1, strcount2 int) (int, int, map[string]string) {
+	for _, k1 := range sMap.Keys {
+		match := false //记录must是否匹配到
+		v1 := qutil.ObjToString(sMap.Map[k1])
+		//	for k1, v1 := range sMap {
+		//qutil.Debug(k1, "++++++++++", v1)
+		if v1 == "" {
+			continue
+		}
+		//匹配必须title
+		for nameM, r := range brandRule["must"] {
+			if convert(k1, r) { //匹配成功
+				v1tmp1 := v1
+				match = true
+				if nameM == "itemname" || nameM == "modal" { //特殊处理itemname
+					hasGoods(table, v1)
+					if nameM == "itemname" {
+						v1tmp1 = filterItem(v1)[0] //过滤itemname
+						if v1tmp1 == "" {
+							break
+						}
+					}
+				}
+				if nameM == "brandname" || nameM == "modal" { //特殊处理brandname
+					if endStrMap["brandname"] == "" {
+						brand, allNull := hasBrand(table, v1)
+						if !allNull {
+							endStrMap["brandname"] = brand[0]
+						}
+					}
+				}
+				//unitprice
+				if nameM == "unitprice" { //处理金额
+					v1tmp1 = dealPrice(k1, v1)[0]
+				}
+				if nameM != "brandname" && endStrMap[nameM] == "" {
+					endStrMap[nameM] = v1tmp1
+				}
+				strcount1++
+			}
+		}
+		//替换其它要保存字段
+		if !match {
+			for nameR, r := range brandRule["replace"] {
+				if convert(k1, r) { //匹配成功
+					v1tmp2 := v1
+					//totalprice
+					if nameR == "totalprice" { //处理金额
+						v1tmp2 = dealPrice(k1, v1)[0]
+					}
+					//number
+					if nameR == "number" { //处理数量
+						varr1, uname1 := dealNumber(v1)
+						v1tmp2 = varr1[0]
+						//从number中获取到的单位
+						if endStrMap["unitname"] == "" && uname1[0] != "" {
+							endStrMap["unitname"] = uname1[0]
+						}
+					}
+					if v1tmp2 != "" {
+						endStrMap[nameR] = v1tmp2
+					}
+					strcount2++
+				}
+			}
+		}
+		//}
+	}
+	return strcount1, strcount2, endStrMap
+}
+
+//数组匹配商品规则
+func (table *Table) matchMapArrBrandRule(aMap *SortMap, brandRule map[string]map[string]string, ka map[string][]string, arrcount1, arrcount2 int) (int, int, map[string][]string) {
+	for _, k0 := range aMap.Keys {
+		match := false //记录must是否匹配到
+		v0 := aMap.Map[k0].([]string)
+		//匹配必须title
+		for nameM, r := range brandRule["must"] {
+			if convert(k0, r) { //匹配成功
+				v0tmp1 := v0
+				match = true
+				if len(ka[nameM]) != 0 && strings.Contains(k0, "描述") { //防止k0匹配到多次 和特殊情况 物料名称 物料描述同时出现
+					continue
+				}
+				if nameM == "itemname" || nameM == "modal" {
+					hasGoods(table, v0...) //判断itemname和modal中有没有商品
+					if nameM == "itemname" {
+						v0tmp1 = filterItem(v0...) //过滤itemname
+					}
+				}
+				if nameM == "brandname" || nameM == "modal" {
+					if len(ka["brandname"]) == 0 {
+						brand, allNull := hasBrand(table, v0...)
+						if !allNull {
+							ka["brandname"] = brand
+						}
+					}
+				}
+				//unitprice
+				if nameM == "unitprice" { //处理金额
+					v0tmp1 = dealPrice(k0, v0...)
+				}
+				if nameM != "brandname" && len(ka[nameM]) == 0 {
+					ka[nameM] = v0tmp1
+				}
+				arrcount1++
+			}
+		}
+		//替换其它要保存字段
+		if !match { //must未匹配,匹配replace
+			for nameR, r := range brandRule["replace"] {
+				if convert(k0, r) { //匹配成功
+					v0tmp2 := v0
+					//totalprice
+					if nameR == "totalprice" { //处理金额
+						v0tmp2 = dealPrice(k0, v0...)
+					}
+					//number
+					if nameR == "number" { //处理数量
+						uname0 := []string{}
+						v0tmp2, uname0 = dealNumber(v0...)
+						if len(ka["unitname"]) == 0 && len(uname0) != 0 {
+							ka["unitname"] = uname0
+						}
+					}
+					if len(v0tmp2) > 0 {
+						ka[nameR] = v0tmp2
+					}
+					arrcount2++
+				}
+			}
+		}
+	}
+	return arrcount1, arrcount2, ka
+}
+
 //初始化lineMapArr,lineMap
-func initLineMapLineMapArr(table *Table, lineMapArr map[string]*SortMap, lineMap map[string]*SortMap) {
+func initLineMapLineMapArr(table *Table) (lineMapArr map[string]*SortMap, lineMap map[string]*SortMap) {
+	lineMapArr = make(map[string]*SortMap)
+	lineMap = make(map[string]*SortMap)
 	for _, key := range table.SortKV.Keys { //遍历table.SortKV.Keys而不是直接遍历table.SortKV.Map是为了得到table头的顺序
 		val := table.SortKV.Map[key]
 		key = regReplAllSpace.ReplaceAllString(key, "")
@@ -3122,6 +3178,7 @@ func initLineMapLineMapArr(table *Table, lineMapArr map[string]*SortMap, lineMap
 			//qutil.Debug("err data:", key, val)
 		}
 	}
+	return lineMapArr, lineMap
 }
 
 func dealArrData(maxNum int, ka map[string][]string) []map[string]string {