str_common.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import regex as re
  2. from loguru import logger
  3. def filter_irregular_expression(input_query):
  4. # logger.debug(f"对一些不规范的表达:转换前 {input_query}")
  5. # 这里对于下个周末这种做转化 把个给移除掉
  6. input_query = number_translator(input_query)
  7. rule = r"[0-9]月[0-9]"
  8. pattern = re.compile(rule)
  9. match = pattern.search(input_query)
  10. if match is not None:
  11. index = input_query.find("月")
  12. rule = r"日|号"
  13. pattern = re.compile(rule)
  14. match = pattern.search(input_query[index:])
  15. if match is None:
  16. rule = r"[0-9]月[0-9]+"
  17. pattern = re.compile(rule)
  18. match = pattern.search(input_query)
  19. if match is not None:
  20. end = match.span()[1]
  21. input_query = input_query[:end] + "号" + input_query[end:]
  22. # 一个半小时
  23. pattern = re.compile(r"(.*半)(?=(小时|月))")
  24. match = pattern.search(input_query)
  25. if match is not None:
  26. test_ge = re.compile(r"(.*)(?=个半)")
  27. test_ge_match = test_ge.match(match.group())
  28. if match.group() == "半":
  29. input_query = input_query.replace("半", "0.5")
  30. elif test_ge_match is not None:
  31. number = test_ge_match.group() + ".5"
  32. input_query = input_query.replace(test_ge_match.group() + "个半", number)
  33. pattern = re.compile(r"小时|月")
  34. match = pattern.search(input_query)
  35. if match is None:
  36. input_query = input_query.replace("个", "")
  37. input_query = input_query.replace("中旬", "15号")
  38. input_query = input_query.replace("傍晚", "午后")
  39. input_query = input_query.replace("大年", "")
  40. input_query = input_query.replace("新年", "春节")
  41. input_query = input_query.replace("五一", "劳动节")
  42. input_query = input_query.replace("白天", "早上")
  43. input_query = input_query.replace(":", ":")
  44. # logger.debug(f"对一些不规范的表达:转换后 {input_query}")
  45. return input_query
  46. def del_keyword(target, rules):
  47. """
  48. 该方法删除一字符串中所有匹配某一规则字串
  49. 可用于清理一个字符串中的空白符和语气助词
  50. :param target: 待处理字符串
  51. :param rules: 删除规则
  52. :return: 清理工作完成后的字符串
  53. """
  54. pattern = re.compile(rules)
  55. res = pattern.sub("", target)
  56. return res
  57. def number_translator(target):
  58. """
  59. 该方法可以将字符串中所有的用汉字表示的数字转化为用阿拉伯数字表示的数字
  60. 如"这里有一千两百个人,六百零五个来自中国"可以转化为
  61. "这里有1200个人,605个来自中国"
  62. 此外添加支持了部分不规则表达方法
  63. 如两万零六百五可转化为20650
  64. 两百一十四和两百十四都可以转化为214
  65. 一六零加一五八可以转化为160+158
  66. 该方法目前支持的正确转化范围是0-99999999
  67. 该功能模块具有良好的复用性
  68. :param target: 待转化的字符串
  69. :return: 转化完毕后的字符串
  70. """
  71. # logger.debug(f"before number_translator: {target}")
  72. pattern = re.compile(r"[一二两三四五六七八九123456789]万[一二两三四五六七八九123456789](?!(千|百|十))")
  73. match = pattern.finditer(target)
  74. for m in match:
  75. group = m.group()
  76. s = group.split("万")
  77. s = list(filter(None, s))
  78. num = 0
  79. if len(s) == 2:
  80. num += word2number(s[0]) * 10000 + word2number(s[1]) * 1000
  81. target = pattern.sub(str(num), target, 1)
  82. pattern = re.compile(r"[一二两三四五六七八九123456789]千[一二两三四五六七八九123456789](?!(百|十))")
  83. match = pattern.finditer(target)
  84. for m in match:
  85. group = m.group()
  86. s = group.split("千")
  87. s = list(filter(None, s))
  88. num = 0
  89. if len(s) == 2:
  90. num += word2number(s[0]) * 1000 + word2number(s[1]) * 100
  91. target = pattern.sub(str(num), target, 1)
  92. pattern = re.compile(r"[一二两三四五六七八九123456789]百[一二两三四五六七八九123456789](?!十)")
  93. match = pattern.finditer(target)
  94. for m in match:
  95. group = m.group()
  96. s = group.split("百")
  97. s = list(filter(None, s))
  98. num = 0
  99. if len(s) == 2:
  100. num += word2number(s[0]) * 100 + word2number(s[1]) * 10
  101. target = pattern.sub(str(num), target, 1)
  102. pattern = re.compile(r"[零一二两三四五六七八九]")
  103. match = pattern.finditer(target)
  104. for m in match:
  105. target = pattern.sub(str(word2number(m.group())), target, 1)
  106. # 星期天表达式替换为星期7
  107. pattern = re.compile("(?<=(周|星期))[末天日]")
  108. match = pattern.finditer(target)
  109. for m in match:
  110. target = pattern.sub("7", target, 1)
  111. pattern = re.compile("(?<!(周|星期))0?[0-9]?十[0-9]?")
  112. match = pattern.finditer(target)
  113. for m in match:
  114. group = m.group()
  115. s = group.split("十")
  116. num = 0
  117. ten = str2int(s[0])
  118. if ten == 0:
  119. ten = 1
  120. unit = str2int(s[1])
  121. num = ten * 10 + unit
  122. target = pattern.sub(str(num), target, 1)
  123. pattern = re.compile("0?[1-9]百[0-9]?[0-9]?")
  124. match = pattern.finditer(target)
  125. for m in match:
  126. group = m.group()
  127. s = group.split("百")
  128. s = list(filter(None, s))
  129. num = 0
  130. if len(s) == 1:
  131. hundred = int(s[0])
  132. num += hundred * 100
  133. elif len(s) == 2:
  134. hundred = int(s[0])
  135. num += hundred * 100
  136. num += int(s[1])
  137. target = pattern.sub(str(num), target, 1)
  138. pattern = re.compile("0?[1-9]千[0-9]?[0-9]?[0-9]?")
  139. match = pattern.finditer(target)
  140. for m in match:
  141. group = m.group()
  142. s = group.split("千")
  143. s = list(filter(None, s))
  144. num = 0
  145. if len(s) == 1:
  146. thousand = int(s[0])
  147. num += thousand * 1000
  148. elif len(s) == 2:
  149. thousand = int(s[0])
  150. num += thousand * 1000
  151. num += int(s[1])
  152. target = pattern.sub(str(num), target, 1)
  153. pattern = re.compile("[0-9]+万[0-9]?[0-9]?[0-9]?[0-9]?")
  154. match = pattern.finditer(target)
  155. for m in match:
  156. group = m.group()
  157. s = group.split("万")
  158. s = list(filter(None, s))
  159. num = 0
  160. if len(s) == 1:
  161. tenthousand = int(s[0])
  162. num += tenthousand * 10000
  163. elif len(s) == 2:
  164. tenthousand = int(s[0])
  165. num += tenthousand * 10000
  166. num += int(s[1])
  167. target = pattern.sub(str(num), target, 1)
  168. # logger.debug(f"after number_translator: {target}")
  169. return target
  170. def word2number(s: str):
  171. """
  172. 方法number_translator的辅助方法,可将[零-九]正确翻译为[0-9]
  173. :param s: 大写数字
  174. :return: 对应的整形数,如果不是数字返回-1
  175. """
  176. return {
  177. "零": 0,
  178. "0": 0,
  179. "一": 1,
  180. "1": 1,
  181. "二": 2,
  182. "两": 2,
  183. "2": 2,
  184. "三": 3,
  185. "3": 3,
  186. "四": 4,
  187. "4": 4,
  188. "五": 5,
  189. "5": 5,
  190. "六": 6,
  191. "6": 6,
  192. "七": 7,
  193. "7": 7,
  194. "八": 8,
  195. "8": 8,
  196. "九": 9,
  197. "9": 9,
  198. }.get(s, -1)
  199. def str2int(s: str):
  200. try:
  201. res = int(s)
  202. except Exception:
  203. res = 0
  204. return res