讲师中心 微信公众号
AI工具推荐 视频效率加速

Python脚本:高效灵活地从多文本文件中提取特定信息

风丽同学_5923

风丽同学_5923

发布时间:2025-11-24 14:23:27

|

579人浏览过

|

来源于php中文网

原创

Python脚本:高效灵活地从多文本文件中提取特定信息

本教程旨在指导读者如何使用python高效且灵活地从目录中的多个文本文件中提取特定行信息。文章将重点讲解如何优化文件读取、利用`pathlib`进行路径操作,以及通过正则表达式替代硬编码的字符串切片,以实现更通用和健壮的数据提取策略。

在处理大量文本文件时,经常需要从每个文件中提取特定的信息。传统的做法可能涉及硬编码的字符串切片或多次文件读取,这不仅效率低下,而且当文件格式稍有变化时,脚本就可能失效。本教程将介绍一种更现代、高效且灵活的方法来解决这一问题。

传统方法的局限性与优化思路

最初的实现可能存在以下问题:

  1. 硬编码的字符串切片: 例如 linea[31:-5] 这样的代码,严重依赖于特定行内容的固定长度和位置。一旦文本文件的格式发生微小变化,这些索引就可能失效,导致提取错误或程序崩溃。
  2. 多次文件读取: 对于同一个文件,为了提取不同的信息而多次打开、读取,这会带来不必要的I/O开销,尤其是在处理大量文件时,会显著降低脚本的执行效率。

为了克服这些局限性,我们应该采纳以下优化策略:

  • 单次文件遍历: 每次打开文件后,一次性遍历其所有行,并在遍历过程中提取所有需要的信息。这能最大程度地减少I/O操作。
  • 灵活的模式匹配: 摒弃硬编码的字符串切片,转而使用更强大的模式匹配工具,如正则表达式,来识别和提取所需的数据。
  • 健壮性设计: 预设默认值来处理信息缺失的情况,并考虑在关键信息无法找到时抛出异常,以便及时发现问题。
  • 现代化路径操作: 利用pathlib模块替代传统的os.path,以更面向对象的方式处理文件和目录路径。

使用pathlib进行文件系统操作

pathlib模块提供了一种面向对象的方式来表示文件系统路径,使得路径操作更加直观和跨平台。它比os.path函数更易读、更安全。

立即学习“Python免费学习笔记(深入)”;

from pathlib import Path

def process_txt_files(directory_path, output_file):
    # 将字符串路径转换为Path对象
    dirpath = Path(directory_path)

    # 使用'w'模式打开输出文件,清空其内容(如果存在),并获取文件句柄
    with open(output_file, 'w') as output_handle:
        # 遍历目录中的所有文件和子目录
        for filepath in dirpath.iterdir():
            # 检查文件是否是.txt文件
            if filepath.suffix == ".txt":
                # 调用extract_lines函数处理每个txt文件
                extract_lines(filepath, output_handle)

# 示例用法
# directory_path = 'C:/Users/rinicholls/Richard/Gnarabup_LiDAR/LiDAR/Gnarabup_South_AVWS/reports'
# output_file = 'density.txt'
# process_txt_files(directory_path, output_file)

在上述代码中,Path(directory_path)创建了一个路径对象,dirpath.iterdir()则返回一个迭代器,用于遍历目录中的所有条目。filepath.suffix可以方便地获取文件的扩展名。

高效的数据提取策略:单次文件遍历与默认值

为了实现单次文件遍历,我们可以在读取文件之前初始化所有待提取信息的默认值。如果在遍历过程中找到了对应的信息,就更新这些值。这样,即使某些信息在文件中不存在,也能保证脚本的正常运行,并输出预设的默认值。

import re
from pathlib import Path

def extract_lines(input_file: Path, output_handle):
    # 初始化所有待提取信息的默认值
    lasinfo_filename = 'No filename defined!'
    projcs_datum = 'No DATUM defined!'
    point_density_statement = 'No point density listed'
    point_density_value = ''

    # 单次打开文件并逐行读取
    with open(input_file, 'r') as lines:
        for line in lines:
            # 使用正则表达式匹配并提取信息
            if m := re.match(r"lasinfo .*? report for '(.*?)'", line):
                lasinfo_filename = m.group(1)
            elif m := re.match(r"^\s*PROJCS\[\"(.*?)\"", line):
                projcs_datum = m.group(1)
            elif m := re.match(r"^point density: all returns ([\d.]+)", line):
                point_density_statement = line.strip() # 提取整行,去除末尾换行符
                point_density_value = m.group(1) # 提取数值部分

    # 将提取到的信息组合成一行,并写入输出文件
    lineout = ",".join([
        lasinfo_filename,
        projcs_datum,
        point_density_statement,
        point_density_value
    ]) + "\n"
    output_handle.write(lineout)

利用正则表达式实现灵活匹配

正则表达式(Regex)是处理字符串模式匹配的强大工具,它能帮助我们精确地定义要查找的文本模式,并从中提取所需的数据,从而替代脆弱的字符串切片。

Claw Code Suite (Python-Only Edition)
Claw Code Suite (Python-Only Edition)

仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...

下载

以下是针对示例文件内容,使用正则表达式进行匹配和提取的详细说明:

  1. 提取 lasinfo 中的文件名:

    • 目标行示例:lasinfo (231025) report for 'Gnarabup_South_sph_e310n6230_1AVWS.las'
    • 正则表达式:r"lasinfo .*? report for '(.*?)'"
      • lasinfo: 匹配字面字符串 "lasinfo "。
      • .*?: 非贪婪匹配任意字符零次或多次,直到下一个模式。
      • report for ': 匹配字面字符串 " report for '"。
      • (.*?): 捕获组,非贪婪匹配并捕获引号内的所有字符。这是我们想要的文件名。
      • ': 匹配结束引号。
    • 提取:m.group(1) 将获取捕获组中的内容。
  2. 提取 PROJCS 中的投影名称:

    • 目标行示例:PROJCS["GDA2020 / MGA zone 50",GEOGCS["GDA2020",...
    • 正则表达式:r"^\s*PROJCS\[\"(.*?)\""
      • ^: 匹配行首。
      • \s*: 匹配零个或多个空白字符(处理行首的缩进)。
      • PROJCS\[\": 匹配字面字符串 "PROJCS[\""。
      • (.*?): 捕获组,非贪婪匹配并捕获双引号内的所有字符(即投影名称)。
      • \": 匹配结束双引号。
    • 提取:m.group(1) 将获取捕获组中的内容。
  3. 提取 point density 中的数值:

    • 目标行示例:point density: all returns 0.25 last only 0.25 (per square units)
    • 正则表达式:r"^point density: all returns ([\d.]+)"
      • ^: 匹配行首。
      • point density: all returns: 匹配字面字符串。
      • ([\d.]+): 捕获组,匹配一个或多个数字或点(用于匹配浮点数)。
    • 提取:m.group(1) 将获取捕获组中的数值。

Python 3.8+ 的 Walrus Operator (:=)

在上述示例代码中,我们使用了 Python 3.8 引入的“海象运算符” (:=)。它允许你在表达式中同时进行赋值和求值,从而简化代码。例如:

if m := re.match(pattern, line):
    # 此时m已经被赋值为re.Match对象,可以直接使用
    extracted_value = m.group(1)

这比传统的两步写法(先赋值再判断)更加简洁:

m = re.match(pattern, line)
if m:
    extracted_value = m.group(1)

完整示例代码

将上述概念整合,一个高效、灵活且健壮的Python脚本如下:

import re
from pathlib import Path

def extract_lines(input_file: Path, output_handle):
    """
    从单个文本文件中提取特定信息,并将结果写入输出句柄。

    Args:
        input_file (Path): 输入文件的Path对象。
        output_handle: 写入结果的输出文件句柄。
    """
    # 初始化所有待提取信息的默认值,以应对信息缺失的情况
    lasinfo_filename = 'No filename defined!'
    projcs_datum = 'No DATUM defined!'
    point_density_statement = 'No point density listed'
    point_density_value = ''

    # 单次打开文件并逐行读取,提高效率
    try:
        with open(input_file, 'r', encoding='utf-8') as file_content:
            for line in file_content:
                # 使用正则表达式进行模式匹配和信息提取
                # 提取lasinfo中的文件名
                if m := re.match(r"lasinfo .*? report for '(.*?)'", line):
                    lasinfo_filename = m.group(1)
                # 提取PROJCS中的投影名称
                elif m := re.match(r"^\s*PROJCS\[\"(.*?)\"", line):
                    projcs_datum = m.group(1)
                # 提取point density行及数值
                elif m := re.match(r"^point density: all returns ([\d.]+)", line):
                    point_density_statement = line.strip() # 获取整行,去除末尾换行符
                    point_density_value = m.group(1) # 获取提取到的数值

    except FileNotFoundError:
        print(f"错误:文件未找到 - {input_file}")
        return
    except Exception as e:
        print(f"处理文件 {input_file} 时发生错误: {e}")
        return

    # 将提取到的信息组合成逗号分隔的字符串,并添加换行符
    lineout = ",".join([
        lasinfo_filename,
        projcs_datum,
        point_density_statement,
        point_density_value
    ]) + "\n"

    # 将结果写入输出文件
    output_handle.write(lineout)

def process_txt_files(directory_path: str, output_file: str):
    """
    扫描指定目录中的所有.txt文件,并对每个文件执行信息提取。

    Args:
        directory_path (str): 包含文本文件的目录路径。
        output_file (str): 结果将写入的输出文件路径。
    """
    dirpath = Path(directory_path)

    # 确保输出目录存在
    if not dirpath.is_dir():
        print(f"错误:目录不存在 - {directory_path}")
        return

    # 使用'w'模式打开输出文件,清空其内容,准备写入
    with open(output_file, 'w', encoding='utf-8') as output_handle:
        # 遍历目录中的所有文件
        for filepath in dirpath.iterdir():
            # 只处理扩展名为.txt的文件
            if filepath.suffix == ".txt":
                extract_lines(filepath, output_handle)

if __name__ == '__main__':
    # 定义要处理的目录和输出文件
    # 请根据您的实际路径修改
    directory_path = 'C:/Users/rinicholls/Richard/Gnarabup_LiDAR/LiDAR/Gnarabup_South_AVWS/reports'
    output_file = 'density_report.txt' # 建议使用更具描述性的文件名

    # 执行文件处理
    process_txt_files(directory_path, output_file)
    print(f"所有.txt文件的信息已提取并写入到 {output_file}")

注意事项与最佳实践

  1. 数据类型转换: 在本例中,point_density_value被提取为字符串。如果后续需要进行数值计算,请记得将其转换为 float 或 int 类型。在输出到文件时,通常需要再次将其转换回字符串。
  2. 错误处理: 尽管我们设置了默认值,但在某些情况下,如果关键信息始终缺失,或者文件本身存在问题(例如,无法打开),抛出异常(raise)可能比静默失败更好。这能让问题在早期阶段就被发现,而不是导致下游数据处理的错误。
  3. 编码: 明确指定文件编码(如 encoding='utf-8')是一个好习惯,可以避免因编码问题导致的文件读取错误。
  4. 通用性: 尽量使正则表达式模式足够通用,以应对未来文件格式的微小变化。如果文件结构差异较大,可能需要更复杂的解析逻辑,甚至考虑使用专门的解析库。
  5. 输出格式: 教程中使用了简单的CSV格式(逗号分隔)。对于更复杂的数据,可以考虑使用JSON、XML或其他结构化数据格式,或者使用csv模块进行更规范的CSV写入。
  6. if __name__ == '__main__': 块: 这个结构确保了 directory_path 和 output_file 的定义以及 process_txt_files 函数的调用只在脚本作为主程序运行时执行,而不是在被其他模块导入时执行。这是一个标准的Python实践。

总结

通过采用pathlib进行现代化的文件路径操作,结合单次文件遍历的高效策略,并利用正则表达式的强大模式匹配能力,我们可以构建出更加灵活、健壮且高效的Python脚本,用于从大量文本文件中提取特定信息。这种方法不仅提高了代码的可维护性,也大大增强了脚本对文件格式变化的适应能力。在实际开发中,始终优先考虑效率、健壮性和代码的可读性,是编写高质量Python程序的关键。

热门AI工具

更多
AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2115

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3182

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1076

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

3619

2025.09.10

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

4276

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

2801

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

7682

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

812

2023.08.11

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

0

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn