从您的评论来看,您的数据实际上是 XML,而您想要的是第一个节点中path
每个(或第一个)file
节点的属性paths
。
就 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
节点而不是第一个节点,或者file
下面的第一个节点paths
而不是所有节点,或者第一个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 等中为您提供慢速实现。
同时,从其他评论中,您要求提供原始帖子中没有的其他内容:
我只需要……把反斜杠变成 /
这很容易。只需调用s.replace('\\', '/')
每条路径s
。
然而,这是一件很奇怪的事情。反过来很常见(它甚至内置在标准库中——<code>os.path.normpath 将在 POSIX 上单独保留斜杠,但在 Windows 上将它们转换为反斜杠),但从原生 Windows 到 POSIX 是通常是较大操作的一部分,例如构建 URL……在这种情况下,您可能希望使用更高级别的函数。
在文件中 - 我想要的结果是 C:\folder\folder
在这里,听起来您想去掉任何尾随反斜杠。再一次,这是一件奇怪的事情,你可能实际上想做一些比这更高级别的事情(比如os.path.dirname
也许?),但很容易:s.rstrip('\\')
.
当然,最后两个是相互矛盾的——如果你想要的结果是C:\folder\folder
,并且你将反斜杠转换为正斜杠,你将不会得到你想要的结果。
但希望我已经给了你足够的东西来建造你真正想要的东西。