从您的 cmets 中,您的数据实际上是 XML,而您想要的是第一个 paths 节点中每个(或第一个)file 节点的 path 属性。
就 XML 解析器而言,这实际上更容易编写,而且更健壮。
例如,这些可能都是有效的file 节点:
<file path="C:\Foo\Bar" />
<file path="C:\Baz\Qux"/>
<file path="C:\Foo\Bar" />
<file path="C:\Spam\Eggs\" alt="other attribute cruft" />
<file alt="other attribute cruft" path="C:\Spam\Eggs\" />
<file path="C:\Spam\Spam\"></file>
您甚至可能会看到这些,无论是否合法:
<file path='C:\Eggs\"Spam Spam Spam"\"Spammity Spam"'/>
您不想尝试以纯文本形式处理所有这些可能性。但是,如果您不处理所有这些文件(以及更多),墨菲定律保证您最终会遇到一个文件,其中包含您不处理的文件。
有很多不同的 XML 解析器,甚至内置在标准库中,但我认为最简单的是 ElementTree。所以:
import os
import os.path
import xml.etree.ElementTree as ET
filepaths = {}
for filename in os.listdir(directory):
try:
doc = ET.parse(os.path.join(directory, filename))
paths = doc.find('paths')
filepaths[filename] = [f.attrib['path'] for f in paths.findall('file')]
except Exception as e:
# You may want to log something, treat different exceptions differently, etc.
pass
应该很容易弄清楚如何更改它以处理所有paths 节点而不是第一个节点,或者paths 下的第一个file 节点而不是所有节点,或者第一个file具有path 属性等的节点。
如果您使用的是 Python 2.x,并且文件非常大,这可能会有点慢。但是您可以通过显式使用cElementTree 来解决这个问题。这样做很常见:
try:
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
如果可能的话,这将为您提供快速的“C”实现,否则,在 CPython 2.5+(包括 3.x,两者合并在一起)、PyPy 等中,这将为您提供慢速实现。
同时,您向其他 cmets 询问了您原始帖子中没有的其他内容:
我只需要……把反斜杠变成 /
这很容易。只需在每条路径s 上调用s.replace('\\', '/')。
但是,这样做有点奇怪。反过来是很常见的(它甚至内置在标准库中——os.path.normpath 将在 POSIX 上单独保留斜杠,但在 Windows 上将它们转换为反斜杠),但是从原生 Windows 到 POSIX 通常是更大的一部分操作,例如构建 URL……在这种情况下,您可能希望使用更高级别的函数。
在文件中 - 我想要的结果是 C:\folder\folder
在这里,听起来您想去掉任何尾随反斜杠。再说一次,这是一件很奇怪的事情,你可能真的想做一些比这更高级的事情(比如os.path.dirname 可能吗?),但很简单:s.rstrip('\\')。
当然,最后两个相互矛盾——如果你想要的结果是C:\folder\folder,并且你将反斜杠转换为正斜杠,你将不会得到你想要的结果。
但希望我已经给了你足够的东西来构建你真正想要的任何东西。