【问题标题】:Python - Replace slashes in CSV filePython - 替换 CSV 文件中的斜杠
【发布时间】:2014-01-20 12:24:42
【问题描述】:

我有一个大约 100 行的 csv 文件。 100 行中的一些单元格的文件路径如下:

C:\\\\Users\\\Simon\\\\Desktop\\\\file.jpg

我想在 python 中打开 csv 文件并仅更改具有三斜杠的行并将它们转换为单个反斜杠。到目前为止,这是我的代码:

import csv

with open('myCsvFile', 'rb') as csvfile:
    SysIndexTwo = csv.reader(csvfile)

for allRows in SysIndexTwo:
  if '\\\\' in allRows:
    writer.writerows(allRows.replace('\\\\', '\\'))

尝试了建议并得到以下错误:

Traceback (most recent call last):
  File "SIPHON2.py", line 7, in <module>
    for allRows in SysIndexTwo:
ValueError: I/O operation on closed file
simon@ubuntu:~/Desktop$ python SIPHON2.py
Traceback (most recent call last):
  File "SIPHON2.py", line 7, in <module>
    for allRows in SysIndexTwo:
ValueError: I/O operation on closed file

这似乎不起作用。有什么想法吗?

谢谢

【问题讨论】:

  • 您的迭代中有四个斜线,而不是三个。
  • 您显然根本没有研究过这个,因为您一直在编辑您的问题。请参阅有关 with 语句、文件和转义特殊字符的文档。
  • 你必须打算你代码的最后三行,在with语句之外,文件会自动关闭
  • 这里至少有三个不同的问题:错误消息是 Steinar 和 Henry 解释的那个;不清楚你是有 3 个还是 4 个反斜杠,因此无法编写正确的代码;那么即使正确计数,不使用原始字符串也会使编写(和读取)代码变得非常困难。仅仅解决这三个问题中的一个并不能神奇地解决另外两个问题。你需要修复所有这些。

标签: python csv


【解决方案1】:

试试:

allRows.replace('\\\\\\', '\\')

请注意,\ 符号需要通过加倍进行转义。

>>> d
'C:\\\\\\Users\\\\\\Simon\\\\\\Desktop\\\\\\file.jpg\n'
>>> d.replace('\\\\\\', '\\')
'C:\\Users\\Simon\\Desktop\\file.jpg\n'
>>> print d.replace('\\\\\\', '\\')
C:\Users\Simon\Desktop\file.jpg

【讨论】:

  • 虽然这应该可行,但这不是一个好建议;原始字符串使所有内容更易于阅读。而 OP 的整个问题似乎是斜线太多,他无法正确计算,所以这在这里非常重要……
【解决方案2】:

您尝试匹配的斜线被视为转义,因此'\\\\' 实际上正在寻找'\\'

尝试使用原始字符串,即r'\\\\'(您需要使用原始字符串进行匹配和替换)。

你也可以把斜线加倍,所以每次你想要\时都使用\\,但这很快就会变得很麻烦

【讨论】:

    【解决方案3】:

    您需要缩进您的实际处理。现在,您在尝试使用它之前退出上下文管理器(定义 CSV 阅读器的 with 语句)。因此,您会收到“对已关闭文件的 IO 操作”错误,因为上下文管理器在您离开文件时将其关闭。

    你想要这个:

    with open('myCsvFile', 'rb') as csvfile:
        reader = csv.reader(csvfile) # Simple names are good, esp. in small scope!
    
        for row in reader: # Indent me!
            pass # Do stuff here.
    

    with 语句可以方便地为您自动关闭文件(除其他外)。但是,这意味着您所做的任何需要您正在使用的文件的工作必须在您离开该块之前完成,因为一旦您离开,文件就会关闭!

    当您初始化 csv 阅读器时,它不会读取整个文件:它会按需读取。因此,当您从 csv 阅读器读取行时,您仍然需要在块内。


    其他说明

    你还有很多其他问题。您似乎不确定您是在尝试清除三个还是四个反斜杠 - 在尝试之前确保您知道自己在做什么!

    您的实际行替换已损坏,因为在您编写它时,allRows 是一个列表,而不是字符串,因此您可能找不到您正在寻找的反斜杠模式。相反,您需要一个内部循环来查看每一行中的每个单元格:

    for row in reader:
        corrected = []
        for cell in row:
            corrected.append(cell.replace('\\\\\\', '\\')) # Gross! See below.
        writer.writerow(corrected)
    

    请注意,我看不到 writer 的定义位置,但看起来它可能会遇到与您的读者相同的问题,如果它是在其他地方的上下文管理器中定义的!

    最后,raw strings 是你的朋友(尽管他们在这里可能对你帮助不大)。通常,只要您想在字符串中使用文字反斜杠,请在字符串前面放一个 r 以省去很多麻烦。 但是,替换奇数个反斜杠仍然是个问题,因为即使是原始字符串也不能以奇数个反斜杠结尾

    因此,要将 \\\ 替换为 \(将三个反斜杠替换为一个),您必须像我在上面的示例中那样将反斜杠加倍。如果你想用两个替换四个反斜杠,你可以使用原始字符串来发挥你的优势:cell.replace(r'\\\\', r'\\') 工作得很好。


    对于后代:您也可以做一些同样丑陋的事情,但以不同的方式,通过在模式字符串的末尾添加一个空格,使其不再以反斜杠结尾,然后剥离额外的空间。下面的行用一个替换了三个反斜杠,但它更hackier(如果你经常这样做,会更慢):

    s = r'This is a \\\ string with \\\ sets \ of \\ three backslash\\\es.'
    print(s.replace(r'\\\ '.strip(), r'\ '.strip()))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-24
      • 2023-03-16
      • 2018-08-30
      • 1970-01-01
      相关资源
      最近更新 更多