【问题标题】:Use Python Regex to search files and return filename使用 Python Regex 搜索文件并返回文件名
【发布时间】:2020-12-12 11:47:28
【问题描述】:

请帮忙。 我正在几个目录中搜索几个 .txt 文件以查找模式。如果有匹配,我想打印匹配的文件名和位置。

这是我的代码:

a = ('Z:/rodney/020year/2020-04/')
b = []
for y in os.listdir(a):
    b.append(a+y+'/')

for filename in b:
    path = filename
    for filenames in listdir(path):
        with open(path+filenames) as currentfile:
            text = currentfile.read()
            loan = re.compile(r'2 NNN                            \d LOANS')
        bb = loan.search(text)
        with open('z:/rodney/results.txt','a') as f:
            f.write(os.path.dirname(path)+' ')
            f.write(filenames[:-4]+'\n')
            f.write(bb)

错误消息 = "TypeError: write() 参数必须是 str,而不是 None"

如果有匹配项,我只想查看匹配项的文件名和位置。我不需要在每个不匹配的文件中都看到“None”。

【问题讨论】:

    标签: python regex file


    【解决方案1】:

    你有:

    bb = loan.search(text)
    

    但是如果在text 中找不到您要查找的字符串,则bb 将不会在None 中出现,因此f.write(bb) 将引发异常(您没有指出哪一行代码引发了异常,所以这是一个有根据的猜测)。

    您需要将代码修改为:

    bb = loan.search(text)
    if bb:
        with open('z:/rodney/results.txt','a') as f:
            f.write(os.path.dirname(path)+' ')
            f.write(filenames[:-4]+'\n')
    

    顺便说一句:

    您在循环中有语句loan = re.compile(r'2 NNN \d LOANS')。因为它是不变的,所以不需要循环。

    【讨论】:

      【解决方案2】:

      您可以通过使用pathlib 避免使用字符串切片和一堆函数来解析文件路径,其中大多数需要的情况已经实现。您还可以通过将re.compile() 移出循环来优化您的代码(创建一次并使用)。与写入结果相同 - 您无需每次都重新打开文件,只需在循环开始前打开一次即可。

      优化代码:

      from pathlib import Path
      import re
      
      src_dir = Path(r"Z:\rodney\020year\2020-04")
      res_fn = r"z:\rodney\results.txt"
      with open(res_fn, "w+") as res_f:
          search_re = re.compile(r"2\sN{3}\s{28}\d\sLOANS")
          for directory in src_dir.iterdir():
              if directory.is_dir():
                  for file in directory.iterdir():
                      if file.is_file():
                          with open(file) as of:
                              bb = search_re.search(of.read())
                              if bb:
                                  print(file.parent, file.stem, file=res_f)
                                  print(bb.group(), file=res_f)
                                  # res_f.write(file.parent + " " + file.stem + "\n" + bb.group())
      

      【讨论】:

      • 您的代码确实执行了 - 不幸的是,“results.txt”文件包含空格......它应该这样做吗?或者这是否意味着代码找不到匹配项??。
      • @belewis6i,冷你添加应该匹配你的正则表达式的小数据样本?
      【解决方案3】:

      根据您的源代码,我对其进行了优化。 我使用os.walk 访问每个 .txt 文件,然后在这些 txt 文件中逐行读取并将其保存在枚举中。然后我将使用正则表达式检查该枚举中的每一行(我引用了 Olvin Roght-san)。如果匹配,它将为您打印出确切的文件位置和行。

      import os
      import re
      
      extension = [".txt"]
      regex =  r"2\sN{3}\s{28}\d\sLOANS"
      re_Search = re.compile(regex)
      path = "Z:\rodney\020year\2020-04"
      for subdir, dirs, files in os.walk(path):
          for file in files:
              file_path = os.path.join(subdir, file)
              ext = os.path.splitext(file)[-1].lower()       
              if ext in extension:
                  with open(file_path, "r") as f:
                      try:
                          f_content = f.readlines()
                      except Exception as e:
                          print(e)
                  for l_idx, line in enumerate(f_content):
                      if re_Search.search(line):
                          print(file_path)
                          print("At line: {l_idx}".format(l_idx = l_idx+1))
              else:
                  print("Nothing!!")
      

      【讨论】:

      • 谢谢 - 不幸的是,在更新我的代码以反映您的更改后,什么也没发生。它没有打印文件或打印“什么都没有!”。代码根本没有执行...?
      • 请再次检查此模式以确保其正确与否?你可以使用记事本++来做到这一点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-28
      • 2012-03-21
      • 2020-06-22
      • 1970-01-01
      • 2013-02-26
      • 2012-03-15
      • 1970-01-01
      相关资源
      最近更新 更多