【问题标题】:Problems reading all the files in a directory?读取目录中的所有文件时出现问题?
【发布时间】:2015-02-24 03:38:19
【问题描述】:

我有一个包含大量 .txt 文件的文件夹,我想阅读它们。为此,首先我使用一些正则表达式来仅捕获我将使用的重要内容。所以我正在做以下事情:

    txt_files =(path, '*.txt')
    important_stuff = re.findall("(\S+)\s+(NC\S+).*\n.*\s(\S+)\s+(AQ\S+)",txt_files)

    print important_stuff

问题在于我获得了TypeError:expected string or buffer 知道如何解决这个问题吗?

【问题讨论】:

  • 你能在codes.open中使用正则表达式/全局扩展作为参数吗?我不知道:)
  • 我觉得有很多更简单的方法来做你想做的事
  • 我编辑了伙计们,谢谢
  • @newWithPython 我敢打赌你的意思是缩进让load_files 不是递归函数。
  • Type error: expected string or buffer 是因为 re.findall(就像我相信所有 re 函数一样)所期望的:一个字符串——不是字符串的list,正如.readlines() 返回。因此,正如我的回答一样,您需要在循环或 listcomp 中应用您需要的任何 re 函数。

标签: python regex python-2.7 io directory


【解决方案1】:

您不能在codecs.open 中使用regex(或glob 扩展)。它需要一个文件名。这就是您收到错误的原因。

所以你不能这样做:

txt_files = [(codecs.open('/the/path/ofthedirectory/*.txt','r','utf8')).readlines()]

您应该使用 os.listdiros.walkglob.iglobglob.glob 迭代器变体)之类的东西,过滤结果,然后打开每个文件。

所以你会得到这样的结果:

# filter to have only txts
txt_files = [p for p in os.listdir('/path/to/dir') if p.endswith('.txt')]
# do your filtering
important_stuff = re.findall("(\S+)\s+(NC\S+).*\n.*\s(\S+)\s+(AQ\S+)", txt_files)

【讨论】:

  • 当我尝试这个时,我得到 TypeError: expected string or buffer,知道如何避免这种情况吗?谢谢!
  • 您是否有机会尝试它显示的部分:所以您不能这样做:...
  • 其实这个解决了问题:important_stuff = re.findall('a_regex', open('/the/path/of_the_files', 'r').read()) print important_stuff
【解决方案2】:

更合理的方法可能是:

import glob, re

txt_files = glob.glob('/the/path/ofthedirectory/*.txt')
important_stuff = [fn for fn in txt_files
                   if re.search(r"(\S+)\s+(NC\S+).*\n.*\s(\S+)\s+(AQ\S+)", fn)]

那是因为 (A) codecs.open 打开一个文件进行读取——它不会打开多个带有通配符的文件,也不会返回文件名; (B) re.findall 作用于单个字符串,而txt_files 肯定不是一个。

这假设您根据文件名选择important_stuff。如果您实际上是在文件的内容上进行选择,则无论如何您都需要打开并阅读每个文件,因此列表理解变得有点笨拙,人们可能更喜欢例如

important_stuff = dict()
for fn in txt_files:
    with codecs.open(fn, 'utf-8') as f:
        contents = f.read()
        if re.search(r"(\S+)\s+(NC\S+).*\n.*\s(\S+)\s+(AQ\S+)", contents):
            important_stuff[fn] = contents

在这里,我正在构建一个从文件名到文件内容的字典,以避免必须打开和读取每个文件两次——一次检查它是否是“重要的东西”,然后再处理它是否是。如果所有这些都不适合记忆,嗯,双重阅读可能更简单——然后我们会去if中的important_stuff = list()important_stuff.append(fn),然后我们会再次打开并读取因此记录为“重要内容”的文件名。

如果在re.search 中匹配的那些组需要被保留(以避免再次扫描它们),可能还有更多,但是如果没有您进一步深入的话,这太难猜了!-)

【讨论】:

  • 如果有那么多文件,glob.iglob 可能会更好。
  • 确实@ReutSharabani,真的:这将是等效的(并节省一些内存),当然只要在选择important_stuff 后的其余代码中不再需要txt_files .
  • 只有在了解迭代器/生成器的工作原理时才使用它们:)
猜你喜欢
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 2012-12-12
  • 2013-12-02
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
相关资源
最近更新 更多