【问题标题】:Python parsing txt, cut specific part of the string between two charactersPython解析txt,在两个字符之间剪切字符串的特定部分
【发布时间】:2021-08-02 16:59:58
【问题描述】:

我正在尝试制作一个脚本,该脚本将从加载的文件中剪切字符串的特定部分。

例如文件中的字符串是(有多个这样的行,并且所有行都应该这样做):

C:\d\projects\project1\folder1\folder2\folder3\folder4\file.h

想要的输出是:

C:\d\projects\project1\folder1\folder2\folder3\folder4

因此,在每一行中,应该只保留文件夹的路径,而不是文件本身。

最好的方法是什么?

【问题讨论】:

  • 是否要从路径中删除所有*.h
  • 是的,所以我必须从一个文件夹中加载所有文件,并在每个文件夹中对所有行(带有文件名的路径)进行这种修改,我只需要一个没有文件名的路径,之后我将删除重复的路径

标签: python string parsing


【解决方案1】:

这对于str.rfind() 来说似乎是一个完美的情况。它找到给定子字符串的最右边的索引,在本例中为\

list = [C:\d\projects\project1\folder1\folder2\folder5\folder1\file3.h, 
        C:\d\projects\project1\folder1\folder2\folder4\folder2\file5.h, 
        C:\d\projects\project1\folder1\folder2\folder3\folder3\file3.h, 
        C:\d\projects\project1\folder1\folder2\folder2\folder4\file4.h, 
        C:\d\projects\project1\folder1\folder2\folder1\folder5\file2.h]
for line in list:
    line = line[ 0 : line.rfind("\\") ]
    print(f"{line}\n")

输出:

C:\d\projects\project1\folder1\folder2\folder5\folder1
C:\d\projects\project1\folder1\folder2\folder4\folder2
C:\d\projects\project1\folder1\folder2\folder3\folder3
C:\d\projects\project1\folder1\folder2\folder2\folder4
C:\d\projects\project1\folder1\folder2\folder1\folder5

【讨论】:

    【解决方案2】:

    所以由于我一开始没有很好地解释我的问题(后来在 cmets 中做了),我不得不解决这个问题,最后这段代码完成了工作:

    for file in directory:
        f = open(file,'r')
        rows = f.readlines()
        array = []
        for i in rows:
            if i.endswith('.h\n'):
                array.append(i.replace(os.path.basename(i), ''))
        wf = open(file,'w')
        for row in array:
            wf.write(row+'\n')
        wf.close()
    

    因此它将遍历文件夹内的所有文件,并从中: C:\d\projects\project1\folder1\folder2\folder5\folder1\file3.h C:\d\projects\project1\folder1\folder2\folder4\folder2\file5.h C:\d\projects\project1\folder1\folder2\folder3\folder3\file3.h C:\d\projects\project1\folder1\folder2\folder2\folder4\file4.h C:\d\projects\project1\folder1\folder2\folder1\folder5\file2.h

    做这个:

    C:\d\projects\project1\folder1\folder2\folder5\folder1 C:\d\projects\project1\folder1\folder2\folder4\folder2 C:\d\projects\project1\folder1\folder2\folder3\folder3 C:\d\projects\project1\folder1\folder2\folder2\folder4 C:\d\projects\project1\folder1\folder2\folder1\folder5

    希望它对某人有所帮助!

    【讨论】:

      【解决方案3】:

      您可以使用pathlib 获得广泛的跨平台路径支持。

      在您的特定示例中:

      from pathlib import PureWindowsPath
      
      p=PureWindowsPath(r'C:\d\projects\project1\folder1\folder2\folder3\folder4\file.h')
      

      那么你就可以随意访问这些部分了:

      >>> p.name
      file.h
      >>> p.parents[0]
      C:\d\projects\project1\folder1\folder2\folder3\folder4
      >>> p.parents[1]
      C:\d\projects\project1\folder1\folder2\folder3
      # etc
      

      你可以改变路径的类型:

      >>> p.as_uri()
      file:///C:/d/projects/project1/folder1/folder2/folder3/folder4/file.h
      >>> p.as_posix()
      C:/d/projects/project1/folder1/folder2/folder3/folder4/file.h
      

      Pathlib 还内置了对通配符的支持。

      给定这样的文件树:

      .
      ├── a
      │   └── sub_a
      │       └── sub_sub_a
      │           └── file.txt
      ├── b
      │   └── sub_b
      │       └── file2.txt
      └── c
          └── file3.txt
      

      你可以这样做:

      for pn in (n for n in p.glob('**/*') if n.is_file()):
          print(pn)
      

      打印:

      /tmp/test/a/sub_a/sub_sub_a/file.txt
      /tmp/test/c/file3.txt
      /tmp/test/b/sub_b/file2.txt
      

      可以是任何包含文件的路径的路径:

      for pn in (n for n in p.glob('**/*') if n.is_file()):
          print(pn.parents[0])
      
      /tmp/test/a/sub_a/sub_sub_a
      /tmp/test/c
      /tmp/test/b/sub_b
      

      这绝对是一种优越的方法。

      【讨论】:

      • 似乎是一个很好的解决方案,但就我而言,我需要从一个特定文件夹加载所有扩展名为 .d 的文件,然后在每个文件中替换行:C:\d\projects \project1\folder1\folder2\folder5\folder1\file3.h C:\d\projects\project1\folder1\folder2\folder4\folder2\file5.h C:\d\projects\project1\folder1\folder2\folder3\folder3 \file3.h C:\d\projects\project1\folder1\folder2\folder2\folder4\file4.h C:\d\projects\project1\folder1\folder2\folder1\folder5\file2.h
      • @John:然后更改 glob 或路径。它不需要是递归的。您还可以使用 pathlib 重命名文件或移动您想要执行的文件。
      【解决方案4】:

      为什么不 split() 像这样使用转义的 \ 并加入除最终文件名项目之外的所有项目。如果您出于其他目的需要文件名,则使用 split() 并使用索引 -1 来获取该部分。

      请注意,我在字符串前面添加了一个 r,因此所有反斜杠都保持不变。你可以阅读这个here

      my_file_location = r"C:\d\projects\project1\folder1\folder2\folder3\folder4\file.h"
      
      print('\\'.join(my_file_location.split('\\')[0:-1])) # path
      >> C:\d\projects\project1\folder1\folder2\folder3\folder4
      
      print(my_file_location.split('\\')[-1]) # filename
      >> file.h
      

      如果你想遍历这些文件名的列表,那么你可以这样做:

      import csv
      
      output_list = []
      with open('my_csv_example.csv', 'r') as f:
          csv_reader = csv.reader(f)
          for row in csv_reader:
              output_list.append('\\'.join(row[0].split('\\')[0:-1]))
      
      with open('my_csv_output_example.csv', mode='w') as f2:
          csv_writer = csv.writer(f2, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
          for row in output_list:
              csv_writer.writerow([row])
      

      输入文件(my_csv_example.csv):

      C:\d\projects\project1\folder1\folder2\folder5\folder1\file3.h
      C:\d\projects\project1\folder1\folder2\folder4\folder2\file5.h
      C:\d\projects\project1\folder1\folder2\folder3\folder3\file3.h
      C:\d\projects\project1\folder1\folder2\folder2\folder4\file4.h
      C:\d\projects\project1\folder1\folder2\folder1\folder5\file2.h
      

      输出文件(my_csv_output_example.csv):

      C:\d\projects\project1\folder1\folder2\folder5\folder1
      C:\d\projects\project1\folder1\folder2\folder4\folder2
      C:\d\projects\project1\folder1\folder2\folder3\folder3
      C:\d\projects\project1\folder1\folder2\folder2\folder4
      C:\d\projects\project1\folder1\folder2\folder1\folder5
      

      由于评论而更新,我认为您缺少的一点是尝试在列表上运行字符串函数。您可能需要列表中的第一个元素,即 0,所以这是您的关键位:

      row[0].split('\\')[0:-1])
      

      【讨论】:

      • 感谢您的帮助!
      • 所以我有一个名为 file.d 的文件,其中包含许多类似的行,它们都是路径,就像示例中的路径一样,我可以在这里使用相同的方式吗?我基本上想加载文件,通过删除文件名来修改它,然后只用路径保存同一个文件。
      • 现在我有这段代码,它从文件夹加载所有文件并将前斜杠替换为反斜杠:对于目录中的文件:open_file = open(file,'r') change_file = open_file.read() change_file = change_file.replace('/', '\\') change_file = change_file.replace('\\', '') write_file = open(file,'w') write_file.write(change_file) write_file.close()
      • 这听起来像是第二个问题。很难阅读评论,因此请从该评论中获取您不知道的内容,然后创建一个引用该评论的新评论作为上下文。如果它为您提出的特定问题提供了答案,则应将其标记为正确。
      • 您的解决方案的问题是我没有定义 my_file_location,我需要从我的文件中调用 readlines() 才能得到我必须修改的一行一行。并且list对象没有属性split。
      猜你喜欢
      • 1970-01-01
      • 2015-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 2013-01-14
      相关资源
      最近更新 更多