re_servicetime.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. #coding:UTF-8
  2. import re
  3. import pandas as pd
  4. import numpy as np
  5. from bs4 import BeautifulSoup
  6. # from sqlalchemy import create_engine
  7. TEST_MODE = False
  8. # before = '(?P<before>' \
  9. # '合同期限|工期/交货期/服务期|工期,\(日历天\)|工期\(交货期\)|合格工期\(天\)|服务期限\(年\)|工期\(天\)' \
  10. # '|工期要求|项目周期|工期\(交货期\)|计划工期\(服务期限\)|服务时限|履行期限|服务周期|供货期' \
  11. # '|合格工期|计划工期\(服务期\)|服务期\(日历天\)|服务,期|交货\(完工\)时间|交付\(服务、完工\)时间' \
  12. # '|交货时间|工期\(日历天\)' \
  13. # '|服务期限为|计划工期|工期要求|服务期限|服务期' \
  14. # '|投标工期|设计工期|合格服务周期|总工期|服务时间|流转期限|维护期限|服务时限|交货期|服务要求' \
  15. # '|完成时间|服务期限|中标工期|项目周期|期限要求|周期|工期|供货期|合同履行日期|计划周期|工期' \
  16. # ')'
  17. before = '(?P<before>' \
  18. '合同期限|工期/交货期/服务期|工期,|工期\(交货期\)|合格工期|服务期限|工期' \
  19. '|工期要求|项目周期|工期\(交货期\)|计划工期\(服务期限\)|服务时限|履行期限|服务周期|供货期限' \
  20. '|合格工期|计划工期\(服务期\)|服务期|服务,期|交货\(完工\)时间|交付\(服务、完工\)时间' \
  21. '|交货时间|工期' \
  22. '|保洁期限|维保期|管理年限|工期承诺|(服务|合同|施工|实施|工程|设计)的?(年限|期限|周期|期:)' \
  23. '|服务期限为|计划工期|工期要求|服务期限|服务期' \
  24. '|投标工期|设计工期|合格服务周期|总工期|服务时间(范围)?|流转期限|维护期限|服务时限|交货期' \
  25. '|完成时间|服务期限|中标工期|项目周期|期限要求|周期|供货期|合同的?履行日期|计划周期' \
  26. '|履约期限|合同的?约定完成时限|合同的?完成日期|承诺完成日期' \
  27. '|合同起始日起|合同的?履约期|履约截止日期|承包期限|合同的?完成日期|特许经营期限' \
  28. '|服务期间|服务履行期|委托(管理)?期限|经营期限|数量' \
  29. '|(工期|服务期限?|交货期限?|服务履行期|合同期限?|履[行约]期限?)说明|存款期限?|(存款|存放|定存)(期|年)限|服务日期' \
  30. '|服务(有效期|年限)|本?合同有效期|协议有效期|项目期限' \
  31. ')'
  32. # ^(?!.*abc).*$ 排除abc字符串
  33. before_wuye = '(?P<before>' \
  34. '(履约期限、地点等简要信息[::,]((履约|时间|期限){1,2}[::])?)' \
  35. ')'
  36. # '|(履约期限、地点等简要信息[^\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,25})' \
  37. # (履约期限、地点等简要信息.{0,25}(?= [\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]+([年月日]|个月)|20[21]))
  38. before2 = '(?P<before2>' \
  39. '自合同签订[之次]日起至|合同签订[之次]日起|自合同签订[之次]日起|签订合同后|系统开发' \
  40. '|合同签订[之次]日起至|自合同签订[之次]日|合同签定后|自签订合同[之次]日起|自合同签订起' \
  41. '|[自从]?合同签[订定]生效[之次]日起|自合同签订后不超过|合同签订日至' \
  42. '|合同签订生效[之次]日起' \
  43. '|本项目招标有效期|招标有效期' \
  44. '|[自从于]?签[订定署字](合同|协议书|协议)并?(期|开始履行|生效|有效期|约定|验收合格|期限|开始服务){0,2}(之[日后]|日期?[后起]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,4}' \
  45. '|[自从于]?(采购)?(合同|协议书|协议)(正式)?签[订定署字](完[成毕])?并?(期|开始履行|生效|验收合格|开始服务|期限|有效期|约定){0,2}(之[日后]|日期?[后起]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,5}' \
  46. '|[^。]{0,4}[自从于][^。]{0,2}20\d{1,2}年\d{1,2}月(\d{1,2}日)?(之[日后]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,5}?' \
  47. '|服务要求' \
  48. '|签订合同起' \
  49. '|项目的有效期限为|项目服务为|签订合同期为' \
  50. '|(合同|协议书)签[订定署字]生效(之[日后]|后|起)[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,4}' \
  51. '|[自从于]服务(合同|协议书|协议)生效(之[日后]|后|起)[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,4}' \
  52. '|(本次)?采购周期' \
  53. '|(项目招标)?履行期|[自从于]?(合同|协议书|协议)生效(之[日后]|后|起)[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,3}' \
  54. '|服务(有效期|年限)|本?合同有效期|协议有效期|(正式)?入驻(之[日后]|后|起|算)+' \
  55. '|(合同|协议书|协议)生效(之[日后]|后|起|算)+' \
  56. '|自?(提供服务|采购人指定|合同约定)(之[日后]|后|起|算)+' \
  57. '|本?项目合同期(为|是)*' \
  58. '|交付使用(之[日后]|后|起|算)+|' \
  59. ')'
  60. # '|[^。]{0,4}[自从于][^。;;,]{0,15}(之[日后]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,5}?' \
  61. # '|[自从于].{2,15}之日[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,4}' \
  62. # before2 用于做开头的表达,需排除一些不合理的
  63. before2_first = '(?P<before2>' \
  64. '自合同签订之日起至|合同签订之日起|自合同签订之日起|签订合同后' \
  65. '|合同签订之日起至|自合同签订之日|合同签定后|自签订合同之日起|自合同签订起' \
  66. '|[自从]?合同签[订定]生效之日起|自合同签订后不超过|合同签订日至' \
  67. '|合同签订生效之日起' \
  68. '|本项目招标有效期|招标有效期' \
  69. '|[自从于]?签[订定署字](合同|协议书|协议)并?(期|开始履行|生效|有效期|约定|验收合格|期限|开始服务){0,2}(之[日后]|日期?[后起]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,4}' \
  70. '|[自从于]?(采购)?(合同|协议书|协议)(正式)?签[订定署字](完[成毕])?并?(期|开始履行|生效|验收合格|开始服务|期限|有效期|约定){0,2}(之[日后]|日期?[后起]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,5}' \
  71. '|服务要求' \
  72. '|签订合同起' \
  73. '|项目的有效期限为|项目服务为|签订合同期为' \
  74. '|(合同|协议书)签[订定署字]生效(之[日后]|后|起)[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,4}' \
  75. '|[自从于]服务(合同|协议书|协议)生效(之[日后]|后|起)[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,4}' \
  76. '|(本次)?采购周期' \
  77. '|(项目招标)?履行期|[自从于]?(合同|协议书|协议)生效(之[日后]|后|起)[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,3}' \
  78. '|服务(有效期|年限)|本?合同有效期|协议有效期|(正式)?入驻(之[日后]|后|起|算)+' \
  79. '|(合同|协议书|协议)生效(之[日后]|后|起|算)+' \
  80. '|自?(提供服务|采购人指定|合同约定)(之[日后]|后|起|算)+' \
  81. '|本?项目合同期(为|是)*' \
  82. '|交付使用(之[日后]|后|起|算)+|' \
  83. ')'
  84. before3 = '(?P<before3>' \
  85. ',?([\((](日历天|施工时间|单位)[\))]|[\((]天[\))]?|[\((]年[\))]?|[\((]月[\))]?)?' \
  86. ')'
  87. before4 = '(?P<before4>' \
  88. '(履约|[本项目原则上]*一招|期限|(服务|合同)(期|)|合计|均为|开工后|不超过|中选后|计划|达到|本合同|)' \
  89. ')'
  90. charac = '(?P<charac>' \
  91. '[::,,【()】]*' \
  92. ')'
  93. # charac前后、center前、after1前 需加
  94. before5 = '(?P<before5>' \
  95. '[自为约是起暂定的拟有效期限从共计至算是要求总服务到本项目]{0,5}' \
  96. ')'
  97. before6 = '(?P<before6>' \
  98. '[自为约是起暂定的拟有效期限从共计至算是要求总服务到本项目]{0,5}' \
  99. ')'
  100. before7 = '(?P<before7>' \
  101. '[自为约是起暂定的拟有效期限从共计至算是要求总服务到本项目]{0,5}' \
  102. ')'
  103. center = '(?P<center>' \
  104. '(\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}[日号]?)' \
  105. '|\d{2,4}[-.年/]\d{1,2}月?[-~~开始起至到—-]+\d{2,4}[-.年/]\d{1,2}月?' \
  106. '|\d{2,4}[-.年/]\d{1,2}[-.月/](\d{1,2}[日号]?)?' \
  107. '|[+\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]+)(\)|)' \
  108. ')'
  109. center2 = '(?P<center2>' \
  110. '[.\d]+个?[月年]' \
  111. ')'
  112. number = '(?P<number>' \
  113. '[\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]+' \
  114. ')'
  115. after = '(?P<after>' \
  116. '[个,,(\(]*(日历|自然|历天|工作|学|)([年月日天周]|周年|整年)(内|)|\)|)|[^。\d一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,3}单位[::]?[年月日]|' \
  117. ')'
  118. # '|周|号|天|个月|个年|((|\(|)年()|\)|)|((|\(|)月()|\)|)|((|\(|)日()|\)|)' \
  119. # '|个日历天|日历天|\(日历天\)|\(天\)|周内|,日历天|工作日|个工作日|' \
  120. after1 = '(?P<after1>' \
  121. '\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}[日号]?)([】)]?)' \
  122. '|\d{2,4}[-.年/]\d{1,2}月?[-~~开始起至到—-]+\d{2,4}[-.年/]\d{1,2}月?' \
  123. ')'
  124. after2 = '(?P<after2>' \
  125. '\d+' \
  126. ')'
  127. after3 = '(?P<after3>' \
  128. '(([\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾][年月日])?)' \
  129. ')'
  130. after4 = '(?P<after4>' \
  131. '[^\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,25}止' \
  132. ')'
  133. reg = re.compile(before + before3 + before7 + charac + before5 + before2 + before4 + before6 + center + after)
  134. reg1 = re.compile(before + before3 + before7 + charac + before5 + after4 + after3)
  135. reg2 = re.compile(before + before3 + before7 + charac + before5 + before2 + before6 + after1)
  136. reg3 = re.compile(before + before3 + before7 + charac + before5 + before2 + after2)
  137. reg4 = re.compile(before2_first[:-2]+before2_first[-1:] + before5 + center + after)
  138. reg5 = re.compile(before + before3 + before7 + charac + before5 + before2 + before4 + before6 + center2 + after)
  139. # reg4 = re.compile(before2[:-2]+before2[-1:] + number + after)
  140. # print(before2[:-2]+before2[-1:])
  141. reg_wuye = re.compile(before_wuye + before4 + before5 + center + after)
  142. reg_not = re.compile(u'(工期延误|工期节点|工期管理'
  143. u'|工期、|终止)'
  144. u'|工期情况|划工期内|服务期内'
  145. u'|(\d{1,2}:\d{1,2}(:\d{1,2})?)')
  146. reg_not1 = re.compile(u'(履行日期:见|服务期限应按|签订合同前,'
  147. u'|务期限:1、|签订日期|证金在合同签|服务期限截止'
  148. u')')
  149. # reg_not2 = re.compile(u'(截止|1\\.|1、)')
  150. # reg_not2 = re.compile(u'')
  151. reg_right_digit = re.compile(u'[\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]+')
  152. reg_right_unit = re.compile(u'[-.年月日号天~~至到—/]')
  153. reg_error = re.compile(u'公告|发布|中')
  154. def re_service_time(text):
  155. if TEST_MODE:
  156. # print(chardet.detect(text))
  157. text = re.sub("\s*", "", text)
  158. text_list = []
  159. text_list.append(text)
  160. # 初始化
  161. all_output_list = []
  162. all_text_index_list = []
  163. for index in range(len(text_list)):
  164. # 初始化
  165. output_list = []
  166. input_str = text_list[index]
  167. # 替换混淆词
  168. for _reg_not in [reg_not, reg_not1]:
  169. match_iter = re.finditer(_reg_not, input_str)
  170. for match in match_iter:
  171. word_index = match.span()
  172. word = match.group()
  173. instead = "#" * len(word)
  174. # print("word, instead, word_index", word, instead, word_index)
  175. input_str = input_str[:word_index[0]] + instead + input_str[word_index[1]:]
  176. if TEST_MODE:
  177. print("input_str", input_str)
  178. # 匹配
  179. output_list, text_index_list = re_find_all_result(reg_wuye, input_str)
  180. if TEST_MODE:
  181. print("output_str, text_index reg_wuye", output_list, text_index_list)
  182. output_list, text_index_list = filter_service_time(output_list, text_index_list)
  183. prob = 0.9
  184. if len(output_list) == 0:
  185. output_list, text_index_list = re_find_all_result(reg2, input_str)
  186. if TEST_MODE:
  187. print("output_str, text_index reg2", output_list, text_index_list)
  188. output_list, text_index_list = filter_service_time(output_list, text_index_list)
  189. prob = 0.8
  190. if len(output_list) == 0:
  191. output_list, text_index_list = re_find_all_result(reg, input_str)
  192. if TEST_MODE:
  193. print("output_str, text_index reg", output_list, text_index_list)
  194. output_list, text_index_list = filter_service_time(output_list, text_index_list)
  195. prob = 0.8
  196. if len(output_list) == 0:
  197. output_list, text_index_list = re_find_all_result(reg1, input_str)
  198. if TEST_MODE:
  199. print("output_str, text_index reg1", output_list, text_index_list)
  200. output_list, text_index_list = filter_service_time(output_list, text_index_list)
  201. prob = 0.8
  202. if len(output_list) == 0:
  203. output_list, text_index_list = re_find_all_result(reg3, input_str)
  204. if TEST_MODE:
  205. print("output_str, text_index reg3", output_list, text_index_list)
  206. output_list, text_index_list = filter_service_time(output_list, text_index_list)
  207. prob = 0.8
  208. if len(output_list) == 0:
  209. output_list, text_index_list = re_find_all_result(reg5, input_str)
  210. if TEST_MODE:
  211. print("output_str, text_index reg5", output_list, text_index_list)
  212. output_list, text_index_list = filter_service_time(output_list, text_index_list)
  213. prob = 0.8
  214. if len(output_list) == 0:
  215. output_list, text_index_list = re_find_all_result(reg4, input_str)
  216. if TEST_MODE:
  217. print("output_str, text_index reg4", output_list, text_index_list)
  218. output_list, text_index_list = filter_service_time(output_list, text_index_list)
  219. prob = 0.5
  220. # 添加
  221. all_output_list += output_list
  222. all_text_index_list += text_index_list
  223. index2word = []
  224. for i in range(len(all_text_index_list)):
  225. word = text[all_text_index_list[i][0]:all_text_index_list[i][1]]
  226. # print(word,text,all_text_index_list[i][0],all_text_index_list[i][1])
  227. if i != len(all_text_index_list)-1:
  228. word = word + " "
  229. index2word.append(word)
  230. # 补充“服务期限12个月,自2022年10月1日至2023年9月30日。”类似数据
  231. 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]:])
  232. if not re.search("20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}",word) and word2:
  233. word2 = word2.group()
  234. 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()
  235. begin = all_text_index_list[i][1] + text[all_text_index_list[i][1]:].index(word2)
  236. end = begin + len(word2)
  237. # print(text[begin:end],"|",word2)
  238. all_text_index_list.append([begin,end])
  239. index2word.append(word2)
  240. # “服务期限12个月,自2022年10月至2023年10月”
  241. 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]:])
  242. if not re.search("20\d{2}[年/.\-]\d{1,2}月?", word) and word3:
  243. word3 = word3.group()
  244. word3 = re.search("20\d{2}[年/.\-]\d{1,2}月?[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾;;]{1,4}20\d{2}[年/.\-]\d{1,2}月?",word3).group()
  245. begin = all_text_index_list[i][1] + text[all_text_index_list[i][1]:].index(word3)
  246. end = begin + len(word3)
  247. all_text_index_list.append([begin, end])
  248. index2word.append(word3)
  249. # print(index2word, all_text_index_list, prob)
  250. if TEST_MODE:
  251. print("index2word all_text_index_list", index2word, all_text_index_list)
  252. return index2word, all_text_index_list, prob
  253. def filter_service_time(output_list, text_index_list):
  254. # 过滤
  255. delete_list = []
  256. for i in range(len(output_list)):
  257. output = output_list[i]
  258. # 日期影响
  259. if re.findall("日", output) and not re.findall(reg_right_unit, re.sub("日期|之日", "", output)):
  260. delete_list.append([output, text_index_list[i]])
  261. print("delete output", output)
  262. continue
  263. # 不包含数字、单位的
  264. if not re.findall(reg_right_digit, output):
  265. delete_list.append([output, text_index_list[i]])
  266. continue
  267. if not re.findall(reg_right_unit, output) and not re.match('^\d{1,3}$', output):
  268. delete_list.append([output, text_index_list[i]])
  269. continue
  270. if not (re.findall("[^之]日|天|年|月|周|星期", output) or re.search("\d{4}[\-\./]\d{1,2}", output)):
  271. delete_list.append([output, text_index_list[i]])
  272. continue
  273. # 包含不要的字
  274. if re.findall(reg_error, output):
  275. delete_list.append([output, text_index_list[i]])
  276. continue
  277. # 类似2019年的
  278. if not re.findall("[-./月日天号]", output):
  279. if len(re.findall("年", output)) == 1:
  280. year_time = re.search("\d+", output)
  281. if year_time is not None and int(year_time.group()) >= 2000:
  282. delete_list.append([output, text_index_list[i]])
  283. # 2022年至2023年
  284. if re.search("\d{2,4}年[至到—-]\d{2,4}年",output):
  285. delete_list.append([output, text_index_list[i]])
  286. for output, text_index in delete_list:
  287. if output in output_list:
  288. output_list.remove(output)
  289. if text_index in text_index_list:
  290. text_index_list.remove(text_index)
  291. if TEST_MODE:
  292. print("delete_list", delete_list)
  293. return output_list, text_index_list
  294. def re_find_all_result(reg, input, unit="", index=0):
  295. """
  296. :param reg: 正则表达式
  297. :param input: 待匹配句子
  298. :param unit: 需要加的单位
  299. :param index: 字符串拼接的开始位置
  300. :return: 正则后的字符串
  301. """
  302. # 全文下标
  303. text_index = []
  304. match1 = re.finditer(reg, input)
  305. output_list = []
  306. for i in match1:
  307. d = i.groupdict()
  308. if TEST_MODE:
  309. for key in d.keys():
  310. if d.get(key):
  311. print('d.get("' + key + '")', d.get(key))
  312. front_len = 0
  313. for key in d.keys():
  314. if d.get(key) and key in ["before", "before2", "before4",
  315. "before5", "before6", "before7", "charac",
  316. "after4"]:
  317. front_len += len(d.get(key))
  318. # 特殊情况
  319. if d.get("before3"):
  320. front_len -= len(d.get("before7"))
  321. front_len -= len(d.get("charac"))
  322. # print(input[i.start():i.start()+front_len],input[i.start()+front_len: i.end()])
  323. # 数量类,排除无“年月日天周”单位的
  324. if re.search("数量",i.group()) and not re.search("[年月日天周]",input[i.start()+front_len: i.end()]):
  325. continue
  326. # 前述表达有排除词的跳过
  327. if re.search("公告|发布|公示",input[i.start():i.start()+front_len]):
  328. continue
  329. # ‘服务日期’只保留x年的
  330. if re.search("服务日期", input[i.start():i.start() + front_len]) \
  331. and (re.search('[日月]',input[i.start()+front_len: i.end()]) or not re.search('年',input[i.start()+front_len: i.end()])):
  332. continue
  333. # 排除某些容易错误的表达
  334. if re.search('^(自合同签订[之次]日起至|合同签订[之次]日起|自合同签订[之次]日起|签订合同后' \
  335. '|合同签订[之次]日起至|自合同签订[之次]日|合同签定后|自签订合同[之次]日起|自合同签订起' \
  336. '|[自从]?合同签[订定]生效[之次]日起|自合同签订后不超过|合同签订日至' \
  337. '|合同签订生效[之次]日起|签订合同起' \
  338. '|[自从于]?签[订定署字](合同|协议书|协议)并?(期|开始履行|生效|有效期|约定|验收合格|期限|开始服务){0,2}(之[日后]|日期?[后起]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,4}' \
  339. '|[自从于]?(采购)?(合同|协议书|协议)(正式)?签[订定署字](完[成毕])?并?(期|开始履行|生效|验收合格|开始服务|期限|有效期|约定){0,2}(之[日后]|日期?[后起]|后|起|算|为)+[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{0,5}' \
  340. '|(合同|协议书)签[订定署字]生效(之[日后]|后|起)[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,4}' \
  341. '|[自从于]服务(合同|协议书|协议)生效(之[日后]|后|起)[^。\d半一二三四五六七八九十壹两叁贰肆伍陆柒捌玖拾]{1,4}' \
  342. ')',input[i.start():i.start() + front_len]):
  343. continue
  344. text_index.append([i.start()+front_len, i.end()])
  345. output_list.append(input[i.start()+front_len: i.end()])
  346. return output_list, text_index
  347. def calculateLen(ss, i):
  348. front_len = 0
  349. back_len = 0
  350. for index in range(i):
  351. front_len += len(ss[index])
  352. for index in range(i+1, len(ss)):
  353. back_len += len(ss[index])
  354. return front_len, back_len
  355. def extract_servicetime(text):
  356. list_servicetime = []
  357. word_list, text_index_list, prob = re_service_time(text)
  358. # print(word_list, text_index_list)
  359. for i in range(len(text_index_list)):
  360. d = {"body": word_list[i], "begin_index": text_index_list[i][0], "end_index": text_index_list[i][1], "prob": prob}
  361. if len(word_list[i]) <= 35:
  362. list_servicetime.append(d)
  363. if TEST_MODE:
  364. print("list_servicetime", list_servicetime)
  365. return list_servicetime
  366. def test_from_str():
  367. # s = """
  368. # """
  369. # s = "5元/年 服务期:交付使用之日起三年; 承诺服务等级"
  370. # s = "交货,1.交货时间:7天,2.交货地点:广东清远市清城区飞来峡镇人民政府高田应急安置点"
  371. s = "本项目服务期限12个月,自2022年10月1日至2023年9月30日。"
  372. s = "服务时间:预计从2022年11月起,12个月"
  373. s = "服务时间:预计从2022年11月起,12个月。" \
  374. "采购,数量:365天,采购,数量(单位):1(年),数量(单位):1(项)," \
  375. "数量:1,单位:月,采购,数量(年):1," \
  376. "1.本合同的期限为壹年,自2023年9月至2024年8月。"
  377. s = "服务期限:与工程施工工期同步,约365天 " \
  378. "服务期限:硬件1年," \
  379. "服务时间:2023年12-2024年12," \
  380. "第十四条,服务时间:2023.12-2024.12,。" \
  381. "第十四条本合同自2023年3月1日起至2024年2月29日止。" \
  382. "服务时间:自2022年10月1日至2023年9月3日" \
  383. "二、垃圾清运委外期限,垃圾委外清运时间为1年,自2023年1月1日起至2023年12月31日止。" \
  384. "服务时间:预计从2022年11月起,12个月。"
  385. # s = '第十四条,服务时间:2023.12-2024.12服务时间'
  386. # 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日,
  387. # '''
  388. print(extract_servicetime(s))
  389. # print(re.findall('(\d{2,4}[-.年/]|\d{1,2}[-.月/]|\d{1,2}[日号]?)+[-~~起至到—]+\d{2,4}[-.年/]', s))
  390. def test_from_csv():
  391. df = pd.read_csv("D:/BIDI_DOC/招标方式_服务期限_提取/serviceTime_text.csv")
  392. result_list = []
  393. for index, row in df.iterrows():
  394. result = extract_servicetime(row["text"])
  395. result_list.append(str(result))
  396. df["new_word"] = pd.DataFrame(result_list)
  397. df.to_csv("D:/BIDI_DOC/招标方式_服务期限_提取/serviceTime_text_new.csv")
  398. def test_from_xlsx():
  399. df = pd.read_excel("D:/BIDI_DOC/比地_文档/service_time_error.xlsx")
  400. result_list = []
  401. for index, row in df.iterrows():
  402. text = row["dochtmlcon"]
  403. soup = BeautifulSoup(text, "lxml")
  404. text = soup.get_text(strip=True)
  405. result = extract_servicetime(text)
  406. result_list.append(str(result))
  407. df["new_word"] = pd.DataFrame(result_list)
  408. df.to_excel("D:/BIDI_DOC/比地_文档/service_time_error_new.xlsx", index=False)
  409. # def test_from_db():
  410. # engine = create_engine("mysql+pymysql://root:pwdformysql0922@192.168.2.170:3306/"
  411. # "exportdb?charset=utf8")
  412. # sql = 'SELECT docid, doctextcon, service_time_1 FROM `wuye_zhouqi_1` where service_time_1 <> "" and service_time_1 is not null;'
  413. # # 建立dataframe
  414. # df = pd.read_sql_query(sql, engine)
  415. # result_list = []
  416. # for index, row in df.iterrows():
  417. # result = extract_servicetime(row["doctextcon"])
  418. # if len(result) > 0:
  419. # temp = ""
  420. # for r in result:
  421. # temp += r.get("body") + "##"
  422. # result_list.append(temp)
  423. # else:
  424. # result_list.append(np.nan)
  425. #
  426. # df["new_service_time"] = pd.DataFrame(result_list)
  427. # df.to_excel("D:/BIDI_DOC/比地_文档/service_time_from_wuye_zhouqi.xlsx", index=False)
  428. if __name__ == '__main__':
  429. test_from_str()