diff --git a/chunk_text.py b/chunk_text.py index c47b18c..8a6239a 100644 --- a/chunk_text.py +++ b/chunk_text.py @@ -581,10 +581,10 @@ def extract_maintenance_groups_and_remaining( ) if is_start: - # 如果是第一个维修表,跳过(不加入 groups,也不标记 used_ids) + # 如果是第一个维修表,跳过(不加入 groups,也不标记 used_ids) if not skipped_first: skipped_first = True - # 注意:这里不清空 current_group,因为前面不可能有 group(第一个 start) + # 注意:这里不清空 current_group,因为前面不可能有 group(第一个 start) current_group = None # 确保不会把之前的非 start 内容误加 continue # 跳过这个 record,不加入任何 group @@ -597,7 +597,7 @@ def extract_maintenance_groups_and_remaining( if current_group is not None: current_group.append(record) - # 处理最后一个 group(仅当有有效 group 时) + # 处理最后一个 group(仅当有有效 group 时) if current_group is not None: groups.append(current_group) used_ids.update(r["id"] for r in current_group) @@ -646,7 +646,7 @@ def is_operation_table_by_first_tr(table_body: str) -> bool: def extract_operation_groups_and_remaining(records, max_following_for_last=23): """ 通过语义判断表格是否为操作项目表(基于第一行内容),并分组。 - 注意:第一个识别到的操作项目表及其后续记录组成的 group 会被跳过(不加入 groups), + 注意:第一个识别到的操作项目表及其后续记录组成的 group 会被跳过(不加入 groups), 但这些记录仍保留在 remaining_records 中。 普通起始标记:组 = [start, ..., next_start - 1] @@ -667,7 +667,7 @@ def extract_operation_groups_and_remaining(records, max_following_for_last=23): if current_group is not None: # 决定是否保留当前积累的 group if not first_group_skipped: - # 跳过第一个 group:不清空 current_group,也不加入 groups 或 used_ids + # 跳过第一个 group:不清空 current_group,也不加入 groups 或 used_ids first_group_skipped = True # 注意:这里不把 current_group 加入 groups,也不更新 used_ids else: @@ -682,7 +682,7 @@ def extract_operation_groups_and_remaining(records, max_following_for_last=23): if current_group is not None: current_group.append(record) - # 处理最后一个 group(如果存在) + # 处理最后一个 group(如果存在) if current_group is not None: if not first_group_skipped: # 整个数据中只有一个 group,且是第一个 → 跳过它 @@ -691,7 +691,7 @@ def extract_operation_groups_and_remaining(records, max_following_for_last=23): groups.append(current_group) used_ids.update(r["id"] for r in current_group) - # —————— 后处理:截断最后一个 group(如果需要) —————— + # —————— 后处理:截断最后一个 group(如果需要) —————— if groups and max_following_for_last is not None: last_group = groups[-1] if len(last_group) > max_following_for_last + 1: # +1 是起始记录本身 @@ -740,7 +740,7 @@ def extract_wxanli(records): # 收集当前切片 slice_records = [] - # 添加前2个记录(如果存在且未超出边界) + # 添加前2个记录(如果存在且未超出边界) for offset in [2, 1]: prev_idx = start_pos - offset if prev_idx >= 0: @@ -1113,7 +1113,7 @@ async def data_replace(data, prefix): def filter_content_bbox(data, max_length=3000): """ - 将 data 中的 text/table/image 内容按字符长度分块(每块不超过 max_length), + 将 data 中的 text/table/image 内容按字符长度分块(每块不超过 max_length), 返回 [{"content": str, "highlight_list": list}, ...] """ chunks = [] @@ -1152,7 +1152,7 @@ def filter_content_bbox(data, max_length=3000): current_content = "" current_highlight_list = [] - # 如果单个 added_content 超过 max_length,仍需保留(避免丢弃) + # 如果单个 added_content 超过 max_length,仍需保留(避免丢弃) if len(added_content) > max_length: # 强制截断或直接放入(这里选择直接放入,避免信息丢失) current_content = added_content[:max_length] @@ -1253,9 +1253,9 @@ def find_ship_info_by_hull(json_file_path, data): print(f"错误:找不到文件 {json_file_path}") return None except json.JSONDecodeError: - print("错误:JSON 文件格式不正确") + print("错误:JSON 文件格式不正确") return None -def merge_short_slices(slices, min_length=30,filename="122-06A0014-B01003_雷达-使用说明书.pdf"): +# def merge_short_slices(slices, min_length=30,filename="122-06A0014-B01003_雷达-使用说明书.pdf"): """ 合并过短的切片: - 如果某切片 content 长度 <= min_length,则将其合并到下一个切片的开头 @@ -1351,6 +1351,111 @@ def merge_short_slices(slices, min_length=30,filename="122-06A0014-B01003_雷达 ins['content'] = content[:newline_idx] + suffix + content[newline_idx:] return result + + +def merge_short_slices(slices, min_length=30, filename="122-06A0014-B01003_雷达-使用说明书.pdf"): + """ + 合并过短的切片: + - 如果某切片 content 长度 <= min_length,则将其合并到下一个切片的开头 + - 若处于末尾无下一个切片,则反向合并到上一个切片末尾 + - content 用换行拼接,positions 顺序拼接 + + Args: + slices: [{"content": str, "positions": [...]}] + min_length: 短切片的字符长度阈值(含) + filename: 用于实体提取的文件名 + + Returns: + 合并后的 slices 列表 + """ + if not slices: + return slices + + result = [] + pending_contents = [] # 缓存等待合并到"下一个"的短切片 content + pending_positions = [] # 缓存对应的 positions + + for ins in slices: + content = ins.get("content", "") or "" + positions = ins.get("positions", []) or [] + + if len(content) <= min_length: + # 暂存,等到下一个正常长度的切片再合并 + pending_contents.append(content) + pending_positions.extend(positions) + else: + # 正常切片:把暂存的短切片合并到它的开头 + if pending_contents: + merged_prefix = "\n".join(pending_contents) + content = merged_prefix + ("\n" if merged_prefix else "") + content + positions = pending_positions + positions + pending_contents = [] + pending_positions = [] + + result.append({ + "content": content, + "positions": positions + }) + + # 收尾:如果末尾还有未合并的短切片(后面没有正常切片可合并) + # 则反向合并到上一个切片末尾 + if pending_contents: + merged_suffix = "\n".join(pending_contents) + if result: + last = result[-1] + last["content"] = (last["content"] or "") + ("\n" if last["content"] else "") + merged_suffix + last["positions"] = (last["positions"] or []) + pending_positions + else: + # 极端情况:所有切片都很短,整体作为一个切片返回 + result.append({ + "content": merged_suffix, + "positions": pending_positions + }) + + try: + final_result = get_entity(filename) + xinghao = find_ship_info_by_hull(SHIP_MODEL_NAME, final_result) + if xinghao is None: # 确保 xinghao 为 None 时不会报错 + xinghao = {"model_name": "", "ship_name": ""} + print("未找到匹配的舰船信息") + + # 安全处理 xinghao 为 None 的情况 + model_name = "" + if xinghao and 'model_name' in xinghao: + model_name = xinghao['model_name'] + + other_data = format_entity_text(final_result) + logger.info(f"文件名实体提取成功: {other_data}") + except Exception as e: + logger.warning(f"文件名实体提取失败: {e}") + other_data = "" + model_name = "" # 确保异常时 model_name 有定义 + + # 将提取的信息(如舰艇名、型号)注入到每个切片的开头 + for ins in result: + content = ins['content'] + # 如果没有提取到有效数据,则跳过注入 + + newline_idx = content.find('\n') + info = other_data + if model_name: + info += f',型号为{model_name}' + + # ===== 修改部分:拼接文件名 + 实体信息 ===== + # 构建前缀:#文件名为:xxx.pdf(实体信息) + filename_prefix = f"#文件名为:{filename}" + if info: + filename_prefix += f"({info})" + # 注意:这里使用全角右括号")"以匹配你的示例,如需半角请改为 ")" + + # 将前缀插入到 content 的最开头 + if content: + ins['content'] = filename_prefix + "\n" + content + else: + ins['content'] = filename_prefix + # ========================================== + + return result def find_and_read_content_list(directory, original_filename, encoding='utf-8'): """ 根据原始文件名,在指定目录及其子目录下查找对应的 _content_list.json 文件并返回内容。 @@ -1505,4 +1610,4 @@ if __name__ == "__main__": for ins in slices_2[:30]: - print(ins) \ No newline at end of file + print(ins)