zhengkun 2 éve
szülő
commit
f8de9763d5

+ 17 - 7
src/jy/admin/rulecheck.go

@@ -266,14 +266,21 @@ func checkCoreReg(field, content, ruleText string) map[string]string {
 		}
 		tmp := strings.Split(ptmp[0], "__")
 		if len(tmp) == 2 {
-			epos := strings.Split(tmp[1], ",")
 			posm := map[string]int{}
-			for _, v := range epos {
-				ks := strings.Split(v, ":")
-				if len(ks) == 2 { //(.*)招标公告(.*)__2:projectname,4:area
-					posm[ks[1]] = qu.IntAll(ks[0])
-				} else {
-					posm[field] = qu.IntAll(ks[0])
+			sufVal := ""
+			sufArr := strings.Split(tmp[1], "~~")
+			if len(sufArr) == 2 { //后缀补
+				posm[field] = qu.IntAll(sufArr[0])
+				sufVal = sufArr[1]
+			} else {
+				epos := strings.Split(tmp[1], ",")
+				for _, v := range epos {
+					ks := strings.Split(v, ":")
+					if len(ks) == 2 { //(.*)招标公告(.*)__2:projectname,4:area
+						posm[ks[1]] = qu.IntAll(ks[0])
+					} else {
+						posm[field] = qu.IntAll(ks[0])
+					}
 				}
 			}
 			var pattern string
@@ -295,6 +302,9 @@ func checkCoreReg(field, content, ruleText string) map[string]string {
 							continue
 						}
 						val := content[pos[p]:pos[p+1]]
+						if val != "" && sufVal != "" {
+							val += sufVal
+						}
 						if sign == -1 {
 							rep[k] = "-" + val
 						} else {

+ 34 - 15
src/jy/extract/extract.go

@@ -1497,16 +1497,24 @@ func extRegCoreToResult(extfrom, text string, tag *map[string]string, j *ju.Job,
 		}
 		tmp := strings.Split(ptmp[0], "__")
 		if len(tmp) == 2 {
-			epos := strings.Split(tmp[1], ",")
 			posm := map[string]int{}
-			for _, v := range epos {
-				ks := strings.Split(v, ":")
-				if len(ks) == 2 { //(.*)招标公告(.*)__2:projectname,4:area
-					posm[ks[1]] = qu.IntAll(ks[0])
-				} else {
-					posm[vre.Field] = qu.IntAll(ks[0])
+			sufVal := ""
+			sufArr := strings.Split(tmp[1], "~~")
+			if len(sufArr) == 2 { //后缀补
+				posm[vre.Field] = qu.IntAll(sufArr[0])
+				sufVal = sufArr[1]
+			} else {
+				epos := strings.Split(tmp[1], ",")
+				for _, v := range epos {
+					ks := strings.Split(v, ":")
+					if len(ks) == 2 { //(.*)招标公告(.*)__2:projectname,4:area
+						posm[ks[1]] = qu.IntAll(ks[0])
+					} else {
+						posm[vre.Field] = qu.IntAll(ks[0])
+					}
 				}
 			}
+
 			var pattern string
 			if strings.Contains(tmp[0], "\\u") {
 				tmp[0] = strings.Replace(tmp[0], "\\", "\\\\", -1)
@@ -1527,6 +1535,9 @@ func extRegCoreToResult(extfrom, text string, tag *map[string]string, j *ju.Job,
 							continue
 						}
 						val := text[pos[p]:pos[p+1]]
+						if val != "" && sufVal != "" {
+							val += sufVal
+						}
 						if string(val) == "" {
 							continue
 						}
@@ -2186,19 +2197,27 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 					tmp["agencyfee"] = tmpAgencyfee
 				}
 
-				if qu.Float64All(tmp["bidamount"]) > 0 && qu.Float64All(tmp["budget"]) > 0 && (qu.Float64All(tmp["bidamount"])/10 > qu.Float64All(tmp["budget"])) {
-					fieldSource["bidamount"] = map[string]interface{}{
-						"ext_type": "",
-						"ext_from": "package",
-					}
-					tmp["bidamount"] = tmpBidamount
-				} else if qu.Float64All(tmp["bidamount"]) < tmpBidamount {
+				if qu.Float64All(tmp["bidamount"]) < tmpBidamount {
 					fieldSource["bidamount"] = map[string]interface{}{
 						"ext_type": "",
 						"ext_from": "package",
 					}
 					tmp["bidamount"] = tmpBidamount
 				}
+
+				//if qu.Float64All(tmp["bidamount"]) > 0 && qu.Float64All(tmp["budget"]) > 0 && (qu.Float64All(tmp["bidamount"])/10 > qu.Float64All(tmp["budget"])) {
+				//	fieldSource["bidamount"] = map[string]interface{}{
+				//		"ext_type": "",
+				//		"ext_from": "package",
+				//	}
+				//	tmp["bidamount"] = tmpBidamount
+				//} else if qu.Float64All(tmp["bidamount"]) < tmpBidamount {
+				//	fieldSource["bidamount"] = map[string]interface{}{
+				//		"ext_type": "",
+				//		"ext_from": "package",
+				//	}
+				//	tmp["bidamount"] = tmpBidamount
+				//}
 			} else {
 				//包数等于1,tmp没有值取包里的值
 				if tmp["budget"] == nil || tmp["budget"] == 0 {
@@ -2369,7 +2388,7 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 		//城市抽取
 		if e.IsExtractCity {
 			//e.NewExtractCity(j, &tmp) //旧版
-			e.ExtractRegionInfo(j, &tmp, false)
+			e.ExtractRegionInfo(j, &tmp, true)
 			e.ExtractRegionClean(&tmp)
 		}
 		//品牌抽取

+ 1 - 0
src/jy/extract/extractudp.go

@@ -127,6 +127,7 @@ func ExtractByUdp(sid, eid string, ra *net.UDPAddr, instanceId ...string) {
 	defer qu.Catch()
 	if ext == nil || ju.IsUpdateRule {
 		ju.IsUpdateRule = false
+		ext = nil
 		ext = &ExtractTask{}
 		ext.Id = qu.ObjToString(ju.Config["udptaskid"])
 		ext.InitTaskInfo()

+ 15 - 0
src/jy/extract/score.go

@@ -124,6 +124,9 @@ func ScoreFields(j *ju.Job, ftag map[string][]*Tag) map[string][]*ju.ExtField {
 				} else if strings.Contains(qu.ObjToString(tmpsvalue.SourceValue), "㎡") {
 					tmps[tmpsindex].Score -= 10
 					tmps[tmpsindex].ScoreItem = append(tmps[tmpsindex].ScoreItem, &ju.ScoreItem{Des: field + `value结果含㎡-10`, Code: field, Value: tmpsvalue.Value, Score: -10})
+				} else if strings.Contains(tmpsvalue.RuleText, "订单总价") && tmpsvalue.Type == "space" {
+					tmps[tmpsindex].Score += 3
+					tmps[tmpsindex].ScoreItem = append(tmps[tmpsindex].ScoreItem, &ju.ScoreItem{Des: field + `value结果含订单总价+3`, Code: field, Value: tmpsvalue.Value, Score: 3})
 				}
 			}
 		}
@@ -261,6 +264,12 @@ func ScoreFields(j *ju.Job, ftag map[string][]*Tag) map[string][]*ju.ExtField {
 							if ranges, ok := length["range"].([]interface{}); ok {
 								gt := qu.IntAll(ranges[0])
 								lte := qu.IntAll(ranges[1])
+								//临时调整人名
+								//if field == "winner" {
+								//	if utf8.RuneCountInString(fmt.Sprint(tmpsvalue.Value)) == 2 || utf8.RuneCountInString(fmt.Sprint(tmpsvalue.Value)) == 3 {
+								//		continue
+								//	}
+								//}
 								//针对指定 buyer -长度0-4 不打分
 								if field == "buyer" || field == "winner" {
 									tmpValue := fmt.Sprint(tmpsvalue.Value)
@@ -287,6 +296,12 @@ func ScoreFields(j *ju.Job, ftag map[string][]*Tag) map[string][]*ju.ExtField {
 						if p, ok := position.(map[string]interface{}); ok {
 							qu.Try(func() {
 								if p["regexp"] != nil {
+									//临时调整人名
+									//if field == "winner" {
+									//	if utf8.RuneCountInString(fmt.Sprint(tmpsvalue.Value)) == 2 || utf8.RuneCountInString(fmt.Sprint(tmpsvalue.Value)) == 3 {
+									//		return
+									//	}
+									//}
 									if field == "buyer" || field == "winner" {
 										//针对指定 buyer -个别  不打分
 										tmpValue := fmt.Sprint(tmpsvalue.Value)

+ 46 - 0
src/jy/extract/score_person.go

@@ -0,0 +1,46 @@
+package extract
+
+import (
+	"unicode"
+	"unicode/utf8"
+)
+
+var family = "赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻柏水窦章云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳酆鲍史唐费廉岑薛雷贺倪汤滕殷罗毕郝邬安常乐于时傅皮卞齐康伍余元卜顾孟平黄和穆萧尹姚邵湛汪祁毛禹狄米贝明臧计伏成戴谈宋茅庞熊纪舒屈项祝董梁杜阮蓝闵席季麻强贾路娄危江童颜郭梅盛林刁钟徐邱骆高夏蔡田樊胡凌霍虞万支柯昝管卢莫经房裘缪干解应宗丁宣贲邓郁单杭洪包诸左石崔吉钮龚程嵇邢滑裴陆荣翁荀羊於惠甄曲家封芮羿储靳汲邴糜松井段富巫乌焦巴弓牧隗山谷车侯宓蓬全郗班仰秋仲伊宫宁仇栾暴甘钭厉戎祖武符刘景詹束龙叶幸司韶郜黎蓟薄印宿白怀蒲邰从鄂索咸籍赖卓蔺屠蒙池乔阴鬱胥能苍双闻莘党翟谭贡劳逄姬申扶堵冉宰郦雍郤璩桑桂濮牛寿通边扈燕冀郏浦尚农温别庄晏柴瞿阎充慕连茹习宦艾鱼容向古易慎戈廖庾终暨居衡步都耿满弘匡国文寇广禄阙东欧殳沃利蔚越夔隆师巩厍聂晁勾敖融冷訾辛阚那简饶空曾毋沙乜养鞠须丰巢关蒯相查后荆红游竺权逯盖益桓公万俟司马上官欧阳夏侯诸葛闻人东方赫连皇甫尉迟公羊澹台公冶宗政濮阳淳于单于太叔申屠公孙仲孙轩辕令狐钟离宇文长孙慕容鲜于闾丘司徒司空丌官司寇仉督子车颛孙端木巫马公西漆雕乐正壤驷公良拓跋夹谷宰父谷梁晋楚闫法汝鄢涂钦段干百里东郭南门呼延归海羊舌微生岳帅缑亢况郈有琴梁丘左丘东门西门商牟佘佴伯赏南宫墨哈谯笪年爱阳佟第五言福百家姓终"
+var familyNames = map[string]bool{}
+
+func initFamilyNames() {
+	for _, s := range family {
+		key := string(s)
+		familyNames[key] = true
+	}
+}
+
+//是否为人名文本
+func IsPersonName(text string) bool {
+	if len(familyNames) == 0 {
+		initFamilyNames()
+	}
+	//长度限制
+	if utf8.RuneCountInString(text) == 2 || utf8.RuneCountInString(text) == 3 {
+		//中文限制
+		if isChineseName(text) {
+			for _, v := range text {
+				key := string(v)
+				if familyNames[key] {
+					return true
+				}
+				break
+			}
+		}
+	}
+	return false
+}
+
+func isChineseName(str string) bool {
+	for _, v := range str {
+		if !unicode.Is(unicode.Han, v) {
+			return false
+		}
+	}
+	return true
+}

+ 78 - 3
src/jy/pretreated/analytable.go

@@ -2,6 +2,7 @@ package pretreated
 
 import (
 	"fmt"
+	"github.com/shopspring/decimal"
 	"jy/clear"
 	u "jy/util"
 	qutil "qfw/util"
@@ -31,7 +32,10 @@ var (
 	//清理表格td中的符号
 	tabletdclear = regexp.MustCompile("[\\s\u3000\u2003\u00a0\\n\u001c、,。_??;;~\\-#\\\\()(){}【】\\[\\]<>《》{}〔〕¥$]*")
 	//判断key是金额,对万元的处理
-	moneyreg = regexp.MustCompile("(预算|费|价|额|规模|投资)")
+	moneyReg = regexp.MustCompile("(预算|费|价|额|规模|投资)")
+	//特殊文本-为表头
+	specHeadReg = regexp.MustCompile("(成交供应商|中选人)")
+
 	//key不需要清理-例如折扣 费率
 	no_clear_key_reg = regexp.MustCompile(`[((](费率|年|月|日|天|日历天|历天)[))]`)
 	//根据表格的内容判断是不是表头,如果含有金额则不是表头
@@ -167,7 +171,7 @@ func CommonDataAnaly(k, tabletag, tabledesc string, v interface{}, isSite bool,
 		}
 	}
 	//对值单位的处理   (预算|费|价|额|规模|投资)
-	if moneyreg.MatchString(k) {
+	if moneyReg.MatchString(k) {
 		v1 += GetMoneyUnit(k, v1)
 	}
 	//先清理key
@@ -258,7 +262,7 @@ func isRepeatArrString(arr1, arr2 []string) bool {
 	return is_r
 }
 
-//中标金额-单位-同时存在-且万元-重构
+//对sortkv重构
 func isResetUnitAmountSortKV(table *Table) {
 	isUnitAmount := 0
 	for _, k := range table.SortKV.Keys {
@@ -276,6 +280,68 @@ func isResetUnitAmountSortKV(table *Table) {
 		table.SortKV.Map["中标金额"] = qutil.ObjToString(table.SortKV.Map["中标金额"]) + "万元"
 	}
 }
+func isResetUnitPriceSortKV(table *Table) {
+	keyArr := []string{"序号", "数量", "单价"}
+	isMatch := true
+	for _, v := range keyArr {
+		if _, ok := table.SortKV.Map[v].(string); !ok {
+			isMatch = false
+			break
+		}
+	}
+	if isMatch && table.SortKV.Map["总价(元)"] == nil {
+		if qutil.ObjToString(table.SortKV.Map["序号"]) == "1" &&
+			qutil.ObjToString(table.SortKV.Map["数量"]) == "1" {
+			table.SortKV.Map["总价(元)"] = table.SortKV.Map["单价"]
+			table.SortKV.Keys = append(table.SortKV.Keys, "总价(元)")
+		}
+	}
+}
+func isResetAmountAggregateSortKV(table *Table) {
+	keyGroup := [][]string{}
+	keyGroup = append(keyGroup, []string{"序号", "标项名称", "总价(元)"})
+	keyGroup = append(keyGroup, []string{"序号", "服务内容", "验收金额(元)"})
+	for _, v := range keyGroup {
+		temp := map[string]bool{}
+		for _, v1 := range v {
+			for _, v2 := range table.SortKV.Keys {
+				if v1 == v2 {
+					temp[v1] = true
+				}
+			}
+		}
+		if len(temp) == 3 {
+			arr1 := u.ConvertInterface(table.SortKV.Map[v[0]])
+			arr2 := u.ConvertInterface(table.SortKV.Map[v[1]])
+			arr3 := u.ConvertInterface(table.SortKV.Map[v[2]])
+			if len(arr1) == len(arr2) && len(arr1) == len(arr3) && len(arr3) > 1 {
+				amount := float64(0)
+				for _, nv := range arr3 {
+					amount = precisionFloat(amount, qutil.Float64All(nv))
+				}
+				if amount > float64(0) {
+					table.SortKV.Map[v[2]] = fmt.Sprintf("%f", amount)
+				}
+				break
+			}
+		}
+	}
+}
+func isReseterialNumberSortKV(table *Table) {
+	arr := u.ConvertInterface(table.SortKV.Map["序号"])
+	if len(arr) > 5 {
+		table.SortKV.Map["序号"] = arr[:3]
+	}
+}
+
+//精度丢失-相加
+func precisionFloat(tmp1, tmp2 float64) float64 {
+	n1 := decimal.NewFromFloat(tmp1)
+	n2 := decimal.NewFromFloat(tmp2)
+	decimalValue := n2.Add(n1)
+	res, _ := decimalValue.Float64()
+	return res
+}
 
 //重置as~keys
 func resetAsKeysBidamount(as *SortMap) {
@@ -321,6 +387,12 @@ func (table *Table) KVFilter(isSite bool, codeSite string) {
 
 	//中标金额-单位-同时存在-且万元-重构
 	isResetUnitAmountSortKV(table)
+	//特殊类~总价需要累加
+	isResetAmountAggregateSortKV(table)
+	//特殊类~单价核算到金额上
+	isResetUnitPriceSortKV(table)
+	//针对序号组过长
+	isReseterialNumberSortKV(table)
 
 	//遍历table.sortkv,进行过滤处理,并放入标准化KV中,如果值是数组跳到下一步处理
 	pre_k := ""
@@ -1421,6 +1493,9 @@ func (table *Table) ComputeRowColIsKeyRation(isSite bool, codeSite string) {
 						for _, td := range tr.TDs {
 							if !MoneyReg.MatchString(td.Val) {
 								//td.BH = true
+								if specHeadReg.MatchString(td.Val) {
+									td.BH = true
+								}
 								td.KeyDirect = 1
 								td.KVDirect = 2
 							}

+ 3 - 3
src/jy/pretreated/colonkv.go

@@ -20,7 +20,7 @@ var (
 	regReplKV2     = regexp.MustCompile("(.+?[\u4e00-\u9fa5))][\\s\u3000\u2003\u00a0]*[::].*[((]?[^\r\n\\s\u3000\u2003\u00a0标段包]+?[))]?)([一二三四五六七八九十]+[、..][^一二三四五六七八九十]+?)")
 	regKV          = regexp.MustCompile("([\\p{Han}][^,,。、.;;\r\n]{1,30}?)[::](.*)")
 	filterK        = regexp.MustCompile("[((\\[【].*?[))\\]】]|<[^>].+?>|[①②③¥·;;‘“'’”,*<>((\\[【、))/\\]】??,。.\".\\s\u3000\u2003\u00a0]+|^[一二三四五六七八九十0-91234567890]+")
-	filterValue    = regexp.MustCompile("(^(无)$|^[\r\n\\s\u3000\u2003\u00a0]+$|^<.*>|(完全响应|普通供应商)$)")
+	filterValue    = regexp.MustCompile("(^(无)$|^[\r\n\\s\u3000\u2003\u00a0]+$|^<.*>|(完全响应|普通供应商|综合排名第一)$)")
 	filterWinner   = regexp.MustCompile(".{2,40}(集团|公司|学校|中心|家具城|门诊|[大中小]学|部|院|局|厂|店|所|队|社|室|厅|会|场|行)")
 	regReplKey     = regexp.MustCompile("^(包(.+[A-Za-z\\d])?|本项目|推荐|的|本次)|([约为元万亿]+|[大小]写|人民币|[全]称|姓名)$")
 	buyerAndAgency = regexp.MustCompile("(代理(机构|人)|采购(人|单位))")
@@ -900,7 +900,7 @@ func GetKvTags(findkvs []*Kv, title string, tagdbs []string, isSite bool, codeSi
 		}
 		if len(tags) > 0 {
 			for _, tk := range tags {
-				if moneyreg.MatchString(tk.Value) {
+				if moneyReg.MatchString(tk.Value) {
 					val += GetMoneyUnit(k, val)
 				}
 				if val != "" {
@@ -919,7 +919,7 @@ func GetKvTags(findkvs []*Kv, title string, tagdbs []string, isSite bool, codeSi
 							}
 						}
 					}
-					if moneyreg.MatchString(tk.Value) {
+					if moneyReg.MatchString(tk.Value) {
 						nextval += GetMoneyUnit(k, nextval)
 					}
 					kvTags[tk.Value] = append(kvTags[tk.Value], &Tag{Key: k, Value: nextval, Weight: tk.Weight})

+ 9 - 5
src/jy/util/util.go

@@ -95,7 +95,7 @@ func UtilInit() {
 	IsUpdateRule = false
 	c := cron.New()
 	c.AddFunc("0 0 8 * * ?", func() {
-		IsUpdateRule = true
+		//IsUpdateRule = true
 	})
 	c.Start()
 
@@ -245,11 +245,15 @@ func FloatFormat(val float64, length int) float64 {
 
 func ConvertInterface(t interface{}) []string {
 	p_list := []string{}
-	if yl_list_1, ok_1 := t.(primitive.A); ok_1 {
-		p_list = qu.ObjArrToStringArr(yl_list_1)
+	if yl_list_0, ok_0 := t.([]string); ok_0 {
+		p_list = yl_list_0
 	} else {
-		if yl_list_2, ok_2 := t.([]interface{}); ok_2 {
-			p_list = qu.ObjArrToStringArr(yl_list_2)
+		if yl_list_1, ok_1 := t.(primitive.A); ok_1 {
+			p_list = qu.ObjArrToStringArr(yl_list_1)
+		} else {
+			if yl_list_2, ok_2 := t.([]interface{}); ok_2 {
+				p_list = qu.ObjArrToStringArr(yl_list_2)
+			}
 		}
 	}
 	return p_list

+ 6 - 8
src/main.go

@@ -26,9 +26,11 @@ func init() {
 	qu.ReadConfig("./res/pricenumber.json", &u.PriceNumberConfig)
 	//初始化util
 	u.UtilInit()
+
 }
 
 func main() {
+
 	extract.ExtractUdpUpdateMachine() //节点上传~构建
 	extract.ExtractUdp()              //udp通知抽取
 	go Router.Run(":" + qu.ObjToString(u.Config["port"]))
@@ -44,12 +46,8 @@ func main() {
 
 //验证规则
 func testMain() {
-	new_detail := `4、成交单位于成交通知书发出后30日内与用户单位签订合同。
-上海大学
-2023-01-04
-点击下载《成交公告》`
-	var inscribe_entity_1 = regexp.MustCompile("\n([\\s]+)?([\u4E00-\u9FA5].{2,20}(公司|集团|单位|委员会|机构|企业|厂|场|院|所|店|中心|市|校|学|局|站|城|处|行|部|队|联合[会|体]))\n([\\s]+)?([0-9]+年[0-9]+月[0-9]+日|[0-9]+[-][0-9]+[-][0-9]+)")
-	new_str := inscribe_entity_1.FindString(new_detail)
-	log.Debug(new_str)
-
+	new_detail := `中标单位:北京脱皮公司`
+	var reg = regexp.MustCompile("(中标单位|成交单位|成交人|供应商)[::][\\s \n]?(.{2,25}(公司))")
+	b := reg.MatchString(new_detail)
+	log.Debug(b)
 }

+ 2 - 2
src/res/tablev1.json

@@ -6,7 +6,7 @@
 		"^(包号|联系|评标|单位|公告|采购|商品|附件|质保|用途|公示|机构|评审|品名|规格|参数|指标|型号|数量|证书).{0,10}$__",
 		"(专家|评委|[打得]分|附件材料)[a-zA-Z0-9]*$__M",
 		"(基本需求.{0,15}|.*联系方式|总计|包组|证书名称|证书编号|合同包|排序|二级建造师|项目负责人及资格证书编号)__M",
-		"(品牌|姓名|起讫桩号|服务期|建设期限|限价|邮编|面积|组织形式|发布单位|招标方式|修建宽度|类别|备注|合计|电话|评审|原因|行业|价格|注册资金|印刷服务|业绩奖项)__",
+		"(品牌|份额|姓名|起讫桩号|服务期|建设期限|限价|邮编|面积|组织形式|发布单位|招标方式|修建宽度|类别|备注|合计|电话|评审|原因|行业|价格|注册资金|印刷服务|业绩奖项)__",
 		"[\\d]+标段$__M",
 		"(\\W{2,10}(名称|参数[及]?要求))$__M"
 	],
@@ -16,7 +16,7 @@
 		"^.{0,6}[打得评总](分)$__M",
 		"(中标|磋商|投标|报|成交)总?(价|金额)__",
 		"(投标|中标)(人|方|单位|供应商)(名称)?__",
-		"(成交|名次|候选|业绩|荣誉|排名|中标|供应商|详见附件及谈判、报价文件|折扣系数|合同期限|委托方|项目所在地|投标文件递交开始间)__"
+		"(成交|名次|合同价款|候选|业绩|荣誉|排名|中标|供应商|详见附件及谈判、报价文件|折扣系数|合同期限|委托方|项目所在地|投标文件递交开始间)__"
 	],
 	"con":[
 		"(是否通过资格|比例|评分结果|中标金额|质量目标|安全目标|承诺工期|推荐顺序|参考对象|工程质量$|工期[((]交货期[))]|合作伙伴|(包名|中标(候选人|供应商).{0,5}|第[一二三四五六七八九十]+中标候选人)[::]?[\\s]*)__M",