Эх сурвалжийг харах

服务、合同时间优化

znj 1 жил өмнө
parent
commit
d2d5987367

+ 64 - 4
BiddingKG/dl/entityLink/entityLink.py

@@ -238,6 +238,63 @@ def init_redis_pool():
     if POOL_REDIS is None:
         POOL_REDIS = ConnectorPool(init_num=1,max_num=10,method_init=getConnect_redis_baseline)
 
+# 插入 Redis
+# def add_redis(company_list):
+#     global ENTERPRISE_HUGE,POOL_REDIS
+#     if ENTERPRISE_HUGE:
+#         _db = POOL_REDIS.getConnector()
+#         for enterprise_name in company_list:
+#             _v = _db.get(enterprise_name)
+#             if _v is None:
+#                 if isLegalNewName(enterprise_name):
+#                     _db.set(enterprise_name,1)
+# 新实体合法判断
+def isLegalNewName(enterprise_name):
+    # head_character_list = ["[",'【',"(",'(']
+    # tail_character_list = ["]",'】',")",')']
+    # 名称开头判断
+    if re.search("^[\da-zA-Z][^\da-zA-Z]|"
+                 "^[^\da-zA-Z\u4e00-\u9fa5\[【((]|"
+                 "^[\[【((].{,1}[\]】))]|"
+                 "^[0〇]|"
+                 "^(20[0-2][0-9]|[0-2]?[0-9]年|[0-1]?[0-9]月|[0-3]?[0-9]日)",enterprise_name):
+        return -1
+    if len(re.findall("[\u4e00-\u9fa5]",enterprise_name))<2:
+        return -1
+    if re.search("╳|*|\*|×|xx|XX",enterprise_name):
+        return -1
+    if re.search("^(省|自治[县州区]|市|县|区|镇|乡|街道)",enterprise_name) and not re.search("^(镇江|乡宁|镇原|镇海|镇安|镇巴|镇坪|镇赉|镇康|镇沅|镇雄|镇远|镇宁|乡城|镇平|市中|市南|市北)",enterprise_name):
+        return -1
+    if re.search("\d{1,2}:\d{2}(:\d{2})?|(rar|xlsx|zip|png|jpg|swf|docx|txt|pdf|PDF|doc|xls|bmp|&?nbsp)",enterprise_name):
+        return -1
+    if re.search("(招标|代理)(人|机构)|联系(人|方式)|中标|候选|第.名",enterprise_name):
+        return -1
+    if re.search("[a-zA-Z\d]{1,2}(包|标段?)|第.批"):
+        return 0
+    return 1
+
+# 过滤掉Redis里值为0的错误实体
+def enterprise_filter(entity_list):
+    global ENTERPRISE_HUGE,SET_ENTERPRISE,POOL_REDIS
+    if ENTERPRISE_HUGE:
+        if POOL_REDIS is None:
+            init_redis_pool()
+        _db = POOL_REDIS.getConnector()
+        remove_list = []
+        try:
+            for entity in entity_list:
+                if entity.entity_type in ['company','org']:
+                    _v = _db.get(entity.entity_text)
+                    if _v==0:
+                        remove_list.append(entity)
+        except Exception as e:
+            traceback.print_exc()
+        POOL_REDIS.putConnector(_db)
+        for _entity in remove_list:
+            entity_list.remove(_entity)
+
+    return entity_list
+
 
 def is_enterprise_exist(enterprise_name):
     global ENTERPRISE_HUGE,SET_ENTERPRISE,POOL_REDIS
@@ -254,8 +311,11 @@ def is_enterprise_exist(enterprise_name):
             if _v is None:
                 return False
             else:
-                log("redis take %.5f of '%s' exists"%(time.time()-_time,enterprise_name))
-                return True
+                if _v:
+                    log("redis take %.5f of '%s' exists"%(time.time()-_time,enterprise_name))
+                    return True
+                else:
+                    return False
         except Exception as e:
             traceback.print_exc()
         return False
@@ -538,5 +598,5 @@ if __name__=="__main__":
     #
     # print("takes %d s"%(time.time()-_time))
     # fix_LEGAL_ENTERPRISE()
-    print(jaccard_score("吉林省九台","吉林省建苑设计集团有限公司"))
-    # print(match_enterprise_max_first("中国南方航空股份有限公司黑龙江分公司"))
+    # print(jaccard_score("吉林省九台","吉林省建苑设计集团有限公司"))
+    print(match_enterprise_max_first("中国南方航空股份有限公司黑龙江分公司"))

+ 69 - 25
BiddingKG/dl/interface/getAttributes.py

@@ -2973,8 +2973,11 @@ def my_timeFormat(_time):
                 if re.search("^\d+$", year):
                     if len(year) == 2:
                         year = "20" + year
-                    if int(year) > int(current_year):
-                        legal = False
+                        if int(year) > int(current_year):
+                            legal = False
+                    else:
+                        if int(year) - int(current_year)>10:
+                            legal = False
                 else:
                     _year = ""
                     for word in year:
@@ -3067,6 +3070,7 @@ def getTimeAttributes(list_entity,list_sentence):
         entity_text = entity.entity_text
         in_attachment = entity.in_attachment
         extract_time = my_timeFormat(entity_text)
+        # print(entity_text,entity_left2)
         # definite_time = "00:00:00"
         if extract_time:
             definite_time_list = []
@@ -3145,7 +3149,6 @@ def getTimeAttributes(list_entity,list_sentence):
                     last_index = item.start() + 1
                 label_prob = label_prob - 0.2 * last_index / len(entity_left2)
                 # print('prob优化',label_prob,extract_time)
-
             # 优化多个并列的时间,如:开标时间和截标时间,截标时间和报名结束时间
             if entity.label in [2,3,9]:
                 if entity.label==2 and re.search("截标|投标.{,2}截止|递交(?:文件)?.{,2}截止|报价.{,2}截止|响应.{,2}截止",entity_left3):
@@ -3192,6 +3195,12 @@ def getTimeAttributes(list_entity,list_sentence):
                     if re.search("(合同.{,2}签[订定署].{,2}|签[订定署].{,2}合同.{,2})(?:时间|日期)|合同签[订定署].{,1}$", entity_left2):
                         dict_time['time_signContract'].append((extract_time[0], 0.5, in_attachment))
                         last_time_type = 'time_signContract'
+                    elif re.search("(合同|服务|履约|(合同|服务)履行).{,2}(?:起始|开始)(?:时间|日期)", entity_left2):
+                        dict_time['time_contractStart'].append((extract_time[0], 0.55, in_attachment))
+                        last_time_type = 'time_contractStart'
+                    elif re.search("(合同|服务|履约).{,2}(?:完成|截止|结束)(?:时间|日期|时限)", entity_left2):
+                        dict_time['time_contractEnd'].append((extract_time[0], 0.55, in_attachment))
+                        last_time_type = 'time_contractEnd'
                     elif re.search("(?:合同|服务|履约|(合同|服务)履行)(?:期限?|有效期)|(?:服务|履约|(合同|服务)履行)(?:时间|日期|周期)|服务[时年]限|合同周期", entity_left2):
                         if re.search("到|至|截[至止]",entity_left) or re.search("前|止|截止",entity_right) or re.search("前",entity_text[-2:]):
                             dict_time['time_contractEnd'].append((extract_time[0], 0.5, in_attachment))
@@ -3199,19 +3208,32 @@ def getTimeAttributes(list_entity,list_sentence):
                         else:
                             dict_time['time_contractStart'].append((extract_time[0], 0.5, in_attachment))
                             last_time_type = 'time_contractStart'
-                    elif re.search("(合同|服务|履约|(合同|服务)履行).{,2}(?:起始|开始)(?:时间|日期)", entity_left2):
-                        dict_time['time_contractStart'].append((extract_time[0], 0.55, in_attachment))
-                        last_time_type = 'time_contractStart'
-                    elif re.search("(合同|服务|履约).{,2}(?:完成|截止|结束)(?:时间|日期|时限)", entity_left2):
-                        dict_time['time_contractEnd'].append((extract_time[0], 0.55, in_attachment))
-                        last_time_type = 'time_contractEnd'
                 else:
                     if re.search("(?:合同|服务|履约|(合同|服务)履行)(?:期限?|有效期)|(?:服务|履约|(合同|服务)履行)(?:时间|日期|周期)|服务[时年]限|合同周期", entity_left2):
-                        dict_time['time_contractStart'].append((extract_time[0], 0.6, in_attachment))
-                        dict_time['time_contractEnd'].append((extract_time[1], 0.6, in_attachment))
+                        # 排除开始和借宿时间一样的错误模板,例:“履约期限:2023年02月15日至2023年02月15日”
+                        if extract_time[0]!=extract_time[1]:
+                            dict_time['time_contractStart'].append((extract_time[0], 0.6, in_attachment))
+                            dict_time['time_contractEnd'].append((extract_time[1], 0.6, in_attachment))
+                            last_time_type = ''
+            # 服务期限表达补充
+            if entity.label==0:
+                re_service = '合同期限|工期/交货期/服务期|工期\(交货期\)|合格工期|服务期限|工期' \
+                    '|工期要求|项目周期|工期\(交货期\)|计划工期\(服务期限\)|服务时限|履行期限|服务周期|供货期限' \
+                    '|合格工期|计划工期\(服务期\)|服务期|服务,期|交货\(完工\)时间|交付\(服务、完工\)时间' \
+                    '|交货时间|工期承诺|(服务|合同|施工|实施|工程|设计)的?(年限|期限|周期|期:)' \
+                    '|服务期限为|计划工期|工期要求|服务期限|服务期' \
+                    '|投标工期|设计工期|合格服务周期|总工期|服务时间(范围)?|流转期限|维护期限|服务时限|交货期' \
+                    '|完成时间|服务期限|中标工期|项目周期|期限要求|供货期|合同履行日期|计划的?周期' \
+                    '|履约期限|合同约定完成时限|合同完成日期|承诺完成日期' \
+                    '|合同起始日起|合同履约期|履约截止日期|承包期限|合同完成日期' \
+                    '|服务期间|服务履行期|委托(管理)?期限'
+                if len(extract_time)==2:
+                    if re.search(re_service,entity_left2):
+                        dict_time['time_contractStart'].append((extract_time[0], 0.5, in_attachment))
+                        dict_time['time_contractEnd'].append((extract_time[1], 0.5, in_attachment))
                         last_time_type = ''
 
-            if re.search("至|到|[日\d][-—]$", entity_left):
+            if re.search("至|到|[日\d][-—]$|[~~]", entity_left):
                 if entity.sentence_index == last_sentence_index:
                     time_type = last_time_index.get(last_time_type)
                     if time_type:
@@ -3401,19 +3423,41 @@ def getOtherAttributes(list_entity):
     if list_serviceTime:
         list_serviceTime_inAtt = [serviceTime for serviceTime in list_serviceTime if serviceTime.in_attachment==1]
         list_serviceTime = [serviceTime for serviceTime in list_serviceTime if serviceTime.in_attachment==0]
-        if not list_serviceTime:
-            list_serviceTime = list_serviceTime_inAtt
-        list_serviceTime.sort(key=lambda x: (x.prob,-x.sentence_index,-x.begin_index), reverse=True)
-        for _serviceTime in list_serviceTime:
-            # 优先取具体时间
-            if re.search("20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}",_serviceTime.entity_text):
-                dict_other["serviceTime"] = _serviceTime.entity_text
-                break
-        if not dict_other["serviceTime"]:
-            max_prob = list_serviceTime[0].prob
-            max_prob_serviceTime = [ent for ent in list_serviceTime if ent.prob==max_prob]
-            max_prob_serviceTime.sort(key=lambda x:(x.sentence_index,x.begin_index))
-            dict_other["serviceTime"] = max_prob_serviceTime[0].entity_text
+        # if not list_serviceTime:
+        #     list_serviceTime = list_serviceTime_inAtt
+        error_serviceTime = []
+        for list_time in [list_serviceTime,list_serviceTime_inAtt]:
+            if not dict_other["serviceTime"]:
+                list_time.sort(key=lambda x: (x.prob,-x.sentence_index,-x.begin_index), reverse=True)
+                for _serviceTime in list_time:
+                    # 优先取具体时间(20XX年x月x日-20XX年x月x日)
+                    if re.search("20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾;;]{,4}20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?",_serviceTime.entity_text):
+                        _extract_time = my_timeFormat(_serviceTime.entity_text)
+                        if _extract_time and len(_extract_time)==2:
+                            # 排除开始和结束时间一样的错误模板,例:“履约期限:2023年02月15日至2023年02月15日”
+                            if _extract_time[0]!=_extract_time[1]:
+                                dict_other["serviceTime"] = _serviceTime.entity_text
+                                break
+                            else:
+                                error_serviceTime.append(_serviceTime.entity_text)
+                if not dict_other["serviceTime"]:
+                    for _serviceTime in list_time:
+                        # 优先取具体时间(20XX年x月-20XX年x月)
+                        if re.search("20\d{2}[年/.\-]\d{1,2}月?[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾;;]{,3}20\d{2}[年/.\-]\d{1,2}月?", _serviceTime.entity_text):
+                            dict_other["serviceTime"] = _serviceTime.entity_text
+                            break
+                if not dict_other["serviceTime"]:
+                    for _serviceTime in list_time:
+                        # 优先取具体时间(20XX年x月x日)
+                        if re.search("20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?",_serviceTime.entity_text):
+                            if _serviceTime.entity_text not in error_serviceTime:
+                                dict_other["serviceTime"] = _serviceTime.entity_text
+                                break
+                if not dict_other["serviceTime"]:
+                    for _serviceTime in list_time:
+                        if _serviceTime.entity_text not in error_serviceTime:
+                            dict_other["serviceTime"] = _serviceTime.entity_text
+                            break
 
     if dict_other['moneysource']:
         dict_other['moneysource'] = turnMoneySource(dict_other['moneysource'])

+ 3 - 3
BiddingKG/dl/interface/predictor.py

@@ -1891,10 +1891,10 @@ class TendereeRuleRecall():
         # 未识别实体召回正则
         self.unrecognized1 = re.compile("(?P<tenderee_left>((遴选|采购|招标|竞价|议价|比选|委托|询比?价|评选|谈判|邀标|邀请|洽谈|约谈)" \
                                         "(人|商|公司|单位|组织|用户|业主|主体|方|部门))" \
-                                        "(信息[,:]?)?((公司|单位)?名称)?([((](全称|盖章)[))])?(是|为|:|:)+)(?P<unrecognized>[^,。::;]+)[,。;::]")
+                                        "(信息[,:]?)?((公司|单位)?名称)?([((](全称|盖章)[))])?(是|:|:)+)(?P<unrecognized>[^,。::;]+)[,。;::]")
         self.unrecognized2 = re.compile("(?P<tenderee_left>((项目|需求|最终|建设|业主|转让|招租|甲|议标|合同主体|挂牌|出租|出让|选取|抽取|抽选|出售|标卖|比价|处置)" \
                                 "(人|公司|单位|组织|用户|业主|主体|方|部门)|文章来源|委托机构|产权所有人|需求?方|买方|业主|(业主|采购人|招标人)联系方式[,:]公司名称:|权属人|甲方当事人|询价书企业|比选发起人|项目单位[,:]单位名称|结算单位)"\
-                                "[))]?(信息[,:])?((公司|单位)?名称)?([((](全称|盖章)[))])?(是|为|:|:)+)(?P<unrecognized>[^,。::;]+)[,。;::]")
+                                "[))]?(信息[,:])?((公司|单位)?名称)?([((](全称|盖章)[))])?(是|:|:)+)(?P<unrecognized>[^,。::;]+)[,。;::]")
         # 未识别实体尾部判断
         self.unrecognized_end1 = re.compile(
             "^[\u4e00-\u9fa5]{2,}?(?:公司|医院|学校|学院|大学|中学|小学|幼儿园|政府|指挥部|办公室|项目部|业主大会|监狱|教育局|委员会|研究所|招标办|采购部|办事处|水利局|公墓|中心|联合社|合作社)")
@@ -2113,7 +2113,7 @@ class TendereeRuleRecall():
                     else:
                         continue
                     # print(_unrecognized)
-                    if re.search("某",_unrecognized) or len(_unrecognized)>15:
+                    if re.search("某|乙方|代理",_unrecognized) or len(_unrecognized)>15:
                         continue
                     begin_index_temp = _match.start()+len(_groupdict['tenderee_left'])
                     for j in range(len(list_tokenbegin)):

+ 57 - 16
BiddingKG/dl/time/re_servicetime.py

@@ -23,13 +23,14 @@ before = '(?P<before>' \
          '|工期要求|项目周期|工期\(交货期\)|计划工期\(服务期限\)|服务时限|履行期限|服务周期|供货期限' \
          '|合格工期|计划工期\(服务期\)|服务期|服务,期|交货\(完工\)时间|交付\(服务、完工\)时间' \
          '|交货时间|工期' \
-         '|保洁期限|维保期|管理年限|工期承诺|(服务|合同|施工|实施|工程|设计)(年限|期限|周期|期:)' \
+         '|保洁期限|维保期|管理年限|工期承诺|(服务|合同|施工|实施|工程|设计)的?(年限|期限|周期|期:)' \
          '|服务期限为|计划工期|工期要求|服务期限|服务期' \
          '|投标工期|设计工期|合格服务周期|总工期|服务时间(范围)?|流转期限|维护期限|服务时限|交货期' \
-         '|完成时间|服务期限|中标工期|项目周期|期限要求|周期|供货期|合同履行日期|计划周期' \
-         '|履约期限|合同约定完成时限|合同完成日期|承诺完成日期' \
-         '|合同起始日起|合同履约期|履约截止日期|承包期限|合同完成日期|特许经营期限' \
-         '|服务期间|服务履行期|委托(管理)?期限|经营期限' \
+         '|完成时间|服务期限|中标工期|项目周期|期限要求|周期|供货期|合同的?履行日期|计划周期' \
+         '|履约期限|合同的?约定完成时限|合同的?完成日期|承诺完成日期' \
+         '|合同起始日起|合同的?履约期|履约截止日期|承包期限|合同的?完成日期|特许经营期限' \
+         '|服务期间|服务履行期|委托(管理)?期限|经营期限|数量' \
+         '|(工期|服务期限?|交货期限?|服务履行期|合同期限?|履[行约]期限?)说明' \
          ')'
 
 
@@ -44,9 +45,12 @@ before2 = '(?P<before2>' \
           '自合同签订之日起至|合同签订之日起|自合同签订之日起|签订合同后|系统开发' \
           '|合同签订之日起至|自合同签订之日|合同签定后|自签订合同之日起|自合同签订起' \
           '|[自从]?合同签[订定]生效之日起|自合同签订后不超过|合同签订日至' \
-          '|合同签订生效之日起|本项目招标有效期' \
+          '|合同签订生效之日起' \
+          '|本项目招标有效期|招标有效期' \
           '|[自从于]?签[订定署字](合同|协议书|协议)并?(期|开始履行|生效|有效期|约定|验收合格|期限|开始服务){0,2}(之[日后]|日期?[后起]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,4}' \
-          '|[自从于]?(采购)?(合同|协议书|协议)(正式)?签[订定署字](完[成毕])?并?(期|开始履行|生效|有效期|约定|验收合格|期限|开始服务){0,2}(之[日后]|日期?[后起]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,5}' \
+          '|[自从于]?(采购)?(合同|协议书|协议)(正式)?签[订定署字](完[成毕])?并?(期|开始履行|生效|验收合格|开始服务|期限|有效期|约定){0,2}(之[日后]|日期?[后起]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,5}' \
+          '|[^。]{0,4}[自从于][^。]{0,2}20\d{1,2}年\d{1,2}月(\d{1,2}日)?(之[日后]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,5}?' \
+          '|服务要求' \
           '|签订合同起' \
           '|项目的有效期限为|项目服务为|签订合同期为' \
           '|(合同|协议书)签[订定署字]生效(之[日后]|后|起)[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,4}' \
@@ -59,10 +63,11 @@ before2 = '(?P<before2>' \
           '|本?项目合同期(为|是)*' \
           '|交付使用(之[日后]|后|起|算)+|' \
           ')'
-        # '|[自从于].{2,15}之日[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,4}' \
+        # '|[^。]{0,4}[自从于][^。;;,]{0,15}(之[日后]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,5}?' \
+    # '|[自从于].{2,15}之日[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,4}' \
 
 before3 = '(?P<before3>' \
-          ',?([\((](日历天|施工时间)[\))]|[\((]天[\))]|[\((]年[\))]|[\((]月[\))])?' \
+          ',?([\((](日历天|施工时间|单位)[\))]|[\((]天[\))]?|[\((]年[\))]?|[\((]月[\))]?)?' \
           ')'
 
 before4 = '(?P<before4>' \
@@ -86,6 +91,7 @@ before7 = '(?P<before7>' \
 
 center = '(?P<center>' \
          '(\d{2,4}[-.年/](\d{1,2}[-.月/])?(\d{0,2}[日号]?)?[-~~开始起至到—-]+(\d{2,4}[-.年/]\d{1,2}[-.月/]\d{0,2}[日号]?|\d{2,4}[-.年/]\d{1,2}[-.月/]?|\d{1,2}[-.月/]\d{1,2}[日号]?|\d{2,4}[-.年/]|\d{1,2}[-.月/]|\d{1,2}[日号]?)' \
+         '|\d{2,4}[-.年/]\d{1,2}月?[-~~开始起至到—-]+\d{2,4}[-.年/]\d{1,2}月?' \
          '|\d{2,4}[-.年/]\d{1,2}[-.月/](\d{1,2}[日号]?)?' \
          '|[+\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]+)(\)|)' \
          ')'
@@ -99,13 +105,14 @@ number = '(?P<number>' \
          ')'
 
 after = '(?P<after>' \
-        '[个,,(\(]*(日历|历天|工作|学|)([年月日天周]|周年|整年)(内|)|\)|)|' \
+        '[个,,(\(]*(日历|自然|历天|工作|学|)([年月日天周]|周年|整年)(内|)|\)|)|[^。\d一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,3}单位[::]?[年月日]|' \
         ')'
         # '|周|号|天|个月|个年|((|\(|)年()|\)|)|((|\(|)月()|\)|)|((|\(|)日()|\)|)' \
         # '|个日历天|日历天|\(日历天\)|\(天\)|周内|,日历天|工作日|个工作日|' \
 
 after1 = '(?P<after1>' \
          '\d{2,4}[-.年/](\d{1,2}[-.月/])?(\d{1,2}[日号])?[-~~开始起至到—]+(\d{2,4}[-.年/]\d{1,2}[-.月/]\d{0,2}[日号]?|\d{2,4}[-.年/]\d{1,2}[-.月/]?|\d{1,2}[-.月/]\d{1,2}[日号]?|\d{2,4}[-.年/]|\d{1,2}[-.月/]|\d{1,2}[日号]?)([】)]?)' \
+         '|\d{2,4}[-.年/]\d{1,2}月?[-~~开始起至到—-]+\d{2,4}[-.年/]\d{1,2}月?' \
          ')'
 
 after2 = '(?P<after2>' \
@@ -248,15 +255,24 @@ def re_service_time(text):
         index2word.append(word)
 
         # 补充“服务期限12个月,自2022年10月1日至2023年9月30日。”类似数据
-        word2 = re.search("^[^。]{,8}20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?.{,4}20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?",text[all_text_index_list[i][1]:])
+        word2 = re.search("^[^。;;::]{,8}20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾;;]{1,4}20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?",text[all_text_index_list[i][1]:])
         if not re.search("20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}",word) and word2:
             word2 = word2.group()
-            word2 = re.search("20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?.{,4}20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?",word2).group()
+            word2 = re.search("20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾;;]{1,4}20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?",word2).group()
             begin = all_text_index_list[i][1] + text[all_text_index_list[i][1]:].index(word2)
             end = begin + len(word2)
             # print(text[begin:end],"|",word2)
             all_text_index_list.append([begin,end])
             index2word.append(word2)
+        # “服务期限12个月,自2022年10月至2023年10月”
+        word3 = re.search("^[^。;;::]{,8}20\d{2}[年/.\-]\d{1,2}月?[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾;;]{1,4}20\d{2}[年/.\-]\d{1,2}月?",text[all_text_index_list[i][1]:])
+        if not re.search("20\d{2}[年/.\-]\d{1,2}月?", word) and word3:
+            word3 = word3.group()
+            word3 = re.search("20\d{2}[年/.\-]\d{1,2}月?[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾;;]{1,4}20\d{2}[年/.\-]\d{1,2}月?",word3).group()
+            begin = all_text_index_list[i][1] + text[all_text_index_list[i][1]:].index(word3)
+            end = begin + len(word3)
+            all_text_index_list.append([begin, end])
+            index2word.append(word3)
 
 
     # print(index2word, all_text_index_list, prob)
@@ -270,9 +286,8 @@ def filter_service_time(output_list, text_index_list):
     delete_list = []
     for i in range(len(output_list)):
         output = output_list[i]
-
         # 日期影响
-        if re.findall("日", output) and not re.findall(reg_right_unit, re.sub("日期", "", output)):
+        if re.findall("日", output) and not re.findall(reg_right_unit, re.sub("日期|之日", "", output)):
             delete_list.append([output, text_index_list[i]])
             print("delete output", output)
             continue
@@ -283,16 +298,23 @@ def filter_service_time(output_list, text_index_list):
         if not re.findall(reg_right_unit, output) and not re.match('^\d{1,3}$', output):
             delete_list.append([output, text_index_list[i]])
             continue
+        if not re.findall("[^之]日|天|年|月|周|星期", output) or re.search("\d{4}[\-\./]\d{1,2}", output):
+            delete_list.append([output, text_index_list[i]])
+            continue
         # 包含不要的字
         if re.findall(reg_error, output):
             delete_list.append([output, text_index_list[i]])
             continue
+
         # 类似2019年的
         if not re.findall("[-./月日天号]", output):
             if len(re.findall("年", output)) == 1:
                 year_time = re.search("\d+", output)
                 if year_time is not None and int(year_time.group()) >= 2000:
                     delete_list.append([output, text_index_list[i]])
+        # 2022年至2023年
+        if re.search("\d{2,4}年[至到—-]\d{2,4}年",output):
+            delete_list.append([output, text_index_list[i]])
     for output, text_index in delete_list:
         if output in output_list:
             output_list.remove(output)
@@ -335,6 +357,13 @@ def re_find_all_result(reg, input, unit="", index=0):
         if d.get("before3"):
             front_len -= len(d.get("before7"))
             front_len -= len(d.get("charac"))
+        # print(input[i.start():i.start()+front_len],input[i.start()+front_len: i.end()])
+        # 数量类,排除无“年月日天周”单位的
+        if re.search("数量",i.group()) and not re.search("[年月日天周]",input[i.start()+front_len: i.end()]):
+            continue
+        # 前述表达有排除词的跳过
+        if re.search("公告|发布",input[i.start():i.start()+front_len]):
+            continue
 
         text_index.append([i.start()+front_len, i.end()])
         output_list.append(input[i.start()+front_len: i.end()])
@@ -354,7 +383,7 @@ def calculateLen(ss, i):
 def extract_servicetime(text):
     list_servicetime = []
     word_list, text_index_list, prob = re_service_time(text)
-    # print(word, text_index_list)
+    # print(word_list, text_index_list)
     for i in range(len(text_index_list)):
         d = {"body": word_list[i], "begin_index": text_index_list[i][0], "end_index": text_index_list[i][1], "prob": prob}
         if len(word_list[i]) <= 35:
@@ -370,10 +399,22 @@ def test_from_str():
     # s = "5元/年 服务期:交付使用之日起三年; 承诺服务等级"
     # s = "交货,1.交货时间:7天,2.交货地点:广东清远市清城区飞来峡镇人民政府高田应急安置点"
     s = "本项目服务期限12个月,自2022年10月1日至2023年9月30日。"
+    s = "服务时间:预计从2022年11月起,12个月"
+    s = "服务时间:预计从2022年11月起,12个月。" \
+        "采购,数量:365天,采购,数量(单位):1(年),数量(单位):1(项)," \
+        "数量:1,单位:月,采购,数量(年):1," \
+        "1.本合同的期限为壹年,自2023年9月至2024年8月。"
+    s = "服务期限:与工程施工工期同步,约365天 " \
+        "服务期限:硬件1年," \
+        "服务时间:2023年12-2024年12," \
+        "第十四条,服务时间:2023.12-2024.12,。" \
+        "第十四条本合同自2023年3月1日起至2024年2月29日止。" \
+        "二、垃圾清运委外期限,垃圾委外清运时间为1年,自2023年1月1日起至2023年12月31日止。"
+    # s = '第十四条,服务时间:2023.12-2024.12服务时间'
 #     s = ''',莆田市财政局走廊及卫生间吊顶改造工程中标结果公告,莆田市财政局走廊及卫生间吊顶改造工程,工程预算价236878元,发包价194240元,招标编号为:宏福莆招字【2020】H001号,该项目招标方式为:邀请招标。2020年04月07日开标,2020年04月07日评标完成,中标主要结果公示如下:中标人名称,福建省东海伟业建设有限公司,中标价:194240元,评标办法,随机抽取法,资格评审结果,注册建造师:合格:余爱华(注册编号:闽235141578763),履约保证金(元):合格:合同金额的10%,施工工期:14日历天,工程质量,备注,被确定为废标、无效标的投标人及原因:合格:无废标,资格审查小组:合格:王宗仙、林慧灵、谢淑青,根据评标结果确定福建省东海伟业建设有限公司为中标人,现在莆田市财政局网上(http://czj.putian.gov.cn/)公示。中标公示期自2020年04月08日至2020年04月10日。投标人对中标结果有异议或认为评标活动存在违法违规行为,可在公示期内向相关主管部门投诉,招标单位:招标代理机构:莆田市财政局,福建省宏福工程管理有限公司,联系电话:0594-2694413,联系电话:15160467775,2020年04月08日,2020年04月08日,
 # '''
     print(extract_servicetime(s))
-    print(re.findall('(\d{2,4}[-.年/]|\d{1,2}[-.月/]|\d{1,2}[日号]?)+[-~~起至到—]+\d{2,4}[-.年/]', s))
+    # print(re.findall('(\d{2,4}[-.年/]|\d{1,2}[-.月/]|\d{1,2}[日号]?)+[-~~起至到—]+\d{2,4}[-.年/]', s))
 
 
 def test_from_csv():