首页 > 解决方案 > 跨多个文本文件查找正则表达式或正则表达式列表并提取匹配行

问题描述

问题

警告:我擅长正则表达式,但我是 Python 新手。我试图尽可能广泛地阅读,但找不到与我的情况相匹配的解决方案,所以我问了这个问题。

我希望完成以下工作:

  1. 循环浏览文件夹中的所有文本文件(有时我可能会使用 .docx / xml 文件,但我会弄清楚细节)。我怀疑这是一个迭代的问题,但我不明白如何在这里做;
  2. 搜索正则表达式或文件中包含的正则表达式列表(如地名词典),最好存储在外部 .txt 或 .csv 文件中;
  3. 打印(或者,更好的是,写入 CSV 或 Pandas)文件名、找到的匹配项以及包含后者的文本行。理想情况下,这些将放在电子表格的不同列中,因此它们可以是逗号分隔的值,但字典也可以。

我使用这种代码取得了一些成功,这使我能够成功打印匹配的行。总共有大约六个小时的 Python 经验,我感到非常高兴。

import re

def main():
        regex = re.compile("regex")
        with open("text_file.txt") as f:
            for line in f:
                result = regex.findall(line)
                if result == None:
                    continue
                elif result == []:
                    continue
                else:
                    print(f, result, line)

main()

问题和目标:

We used to call Bob "Little Bobby"

我的正则表达式“Bob(by)?” 将匹配“鲍勃”和“鲍比”。但是我的代码会打印出这样的东西(如果我没记错的话)。

<_io.TextIOWrapper name='text_file.txt' mode='r' encoding='UTF-8'> [('Bob', ''), ('Bobby', ('by')) We used to call Bob "Little Bobby"

相反,我希望它打印两行(一行用于“Bob”匹配,另一行用于“Bobby”匹配。如果我没记错的话,这可以在 grep 中相对容易地完成,但我在重新模块文档。

标签: pythonregexpython-3.7text-mining

解决方案


  1. 循环浏览文件夹中的所有文本文件(有时我可能会使用 .docx / xml 文件,但我会弄清楚细节)。我怀疑这是一个迭代的问题,但我不明白如何在这里做;

是的,你需要迭代。我建议使用os.listdirglob.glob根据您的需要。

例子:

import glob
for filename in glob.glob('/path/to/my/dir', '*.txt'):
    print(filename)
    # do other stuff with filename
  1. 搜索正则表达式或文件中包含的正则表达式列表(如地名词典),最好存储在外部 .txt 或 .csv 文件中;

我建议使用re.findallor re.finditer

例子:

import re

my_re = re.compile('whatever your regex is')
with open(filename) as f:
    file_contents = f.read()
    for match in my_re.findall(file_contents):
        print(match)
        # do whatever you want with the match here

要从匹配中提取组,您需要使用该.groups函数。

  1. 打印(或者,更好的是,写入 CSV 或 Pandas)文件名、找到的匹配项以及包含后者的文本行。理想情况下,这些将放在电子表格的不同列中,因此它们可以是逗号分隔的值,但字典也可以。

您可以将所有数据加载到 s 的 Pythonlistdict,然后使用该csv库将其输出到 CSV。

例子:

import csv

list_of_data = [{ ... }, { ... }]

with open(output_filename, 'w+') as f:
    # this specifies what the headers of your CSV will be.
    # you can also just specify a list of strings here
    fieldnames = list_of_data[0].keys()
    writer = csv.DictWriter(f, fieldnames=fieldnames)

    writer.writeheader()
    for item in list_of_data:
        writer.writerow(item)

推荐阅读