如何在Python中使用多个分隔符拆分字符串而不删除分隔符?

3

我目前有一个txt文件中的文件名列表,我正在尝试对它们进行排序。首先,我尝试将它们拆分成列表,因为它们都在一行中。列表中有3种不同类型的文件。我能够将列表拆分,但我希望在最终结果中保留分隔符,但我找不到这样做的方法。我拆分文件的方法如下:

import re

def breakLines():
    unsorted_list = []
    file_obj = open("index.txt", "rt")
    file_str = file_obj.read()

    unsorted_list.append(re.split('.txt|.mpd|.mp4', file_str))

    print(unsorted_list)

breakLines()

我在这里发现了DeepSpace的回答非常有帮助(使用Python拆分包含“(”和“)”的字符串并保留分隔符),但它似乎只适用于单个字符。
编辑:
样例输入:
file_name1234.mp4file_name1235.mp4file_name1236.mp4file_name1237.mp4
期望输出:
file_name1234.mp4 file_name1235.mp4 file_name1236.mp4 file_name1237.mp4

你需要类似于 re.split('(.txt|.mpd|.mp4)', file_str) 这样的东西吗?你的输入和期望输出是什么? - Jean-François Fabre
@Jean-FrançoisFabre,这确实起作用了,但它将扩展名放入数组内部的自己变量中。有没有办法将扩展名与文件保持在一起?输入看起来有点像“file_name0384.mp4file_name3489.mp4file_name9400.mp4file_name2333.mp4”等。我想要的是"file_name0384.mp4","file_name3489.mp4","file_name9400.mp4","file_name2333.mp4"等。 - Alexiz Hernandez
请编辑您的问题,提供样例输入和输出,否则适用重复规则。 - Jean-François Fabre
1
@user3483203编辑了问题,所以它不再是重复的了。我重新打开了这个问题,但我不喜欢在关闭者背后这样做,因此提前通知一下。 - Jean-François Fabre
@Jean-FrançoisFabre同意,不再是重复。 - user3483203
显示剩余3条评论
1个回答

6
re.split中,关键是将分割模式括在括号中,以便它保留在re.split的结果中。你的尝试是:
>>> s = "file_name1234.mp4file_name1235.mp4file_name1236.mp4file_name1237.mp4"
>>> re.split('.txt|.mpd|.mp4', s)
['file_name1234', 'file_name1235', 'file_name1236', 'file_name1237', '']

好的,那个不起作用(而且点需要转义才能真正符合扩展的要求),所以让我们尝试:

>>> re.split('(\.txt|\.mpd|\.mp4)', s)
['file_name1234',
'.mp4',
 'file_name1235',
 '.mp4',
 'file_name1236',
 '.mp4',
 'file_name1237',
 '.mp4',
 '']

这段代码可以实现你想要的功能,但是它会将文件名和扩展名分开并在最后留下一个空格,这不是你想要的(除非你想进行丑陋的后处理)。此外,这是一个重复的问题:如何在Python中拆分字符串并保留分隔符?

但是,你需要使用re.findall而不是re.split:

>>> s = "file_name1234.mp4file_name1235.mp4file_name1236.mp4file_name1237.mp4"
>>> re.findall('(\w*?(?:\.txt|\.mpd|\.mp4))',s)
['file_name1234.mp4',
 'file_name1235.mp4',
 'file_name1236.mp4',
 'file_name1237.mp4']

这个表达式匹配单词字符(基本上是数字、字母和下划线),后面跟着扩展名。为了能够创建OR,我在主组内创建了一个非捕获组。

如果您有更奇特的文件名,就不能再使用\w,但它仍然可以合理地工作(您可能需要一些str.strip后处理来删除前导/尾随空格,这些空格很可能不是文件名的一部分):

>>> s = " file name1234.mp4file-name1235.mp4 file_name1236.mp4file_name1237.mp4"
>>> re.findall('(.*?(?:\.txt|\.mpd|\.mp4))',s)
[' file name1234.mp4',
 'file-name1235.mp4',
 ' file_name1236.mp4',
 'file_name1237.mp4']

有时候你会觉得需要使用re.split,但实际上你需要用的是re.findall,反之亦然。


这太棒了!非常感谢!只有一个问题,如果将来我的文件名中有空格或其他符号,这会成为问题吗?还是它仍然可以正常工作? - Alexiz Hernandez
1
如果您接受所有字符,那么这个代码就可以工作:'(.*?(?:\.txt|\.mpd|\.mp4))'。如果需要的话,您可以使用 strip() 函数。 - Jean-François Fabre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接