如何在Python中将多行字符串拆分为多行?

3

我有一个多行字符串:

inputString = "Line 1\nLine 2\nLine 3"

我想要一个数组,每个元素最多只有两行内容,如下所示:
outputStringList = ["Line 1\nLine2", "Line3"]

我能在Python中将inputString转换为outputStringList吗?非常感谢您的帮助。


1
你目前尝试了什么?请展示你的代码。 - Soviut
1
此外,请解释为什么您希望某些行被拆分,而其他行不需要。这毫无意义。 - Soviut
7个回答

3

你可以尝试查找两行代码(其中包含前瞻以避免捕获换行符),或者只查找一行(以处理最后一行)。我扩展了你的示例,以展示它适用于多于3行的情况(有一个小技巧:在结尾处添加一个换行符来处理所有情况):

import re

s = "Line 1\nLine 2\nLine 3\nline4\nline5"
result = re.findall(r'(.+?\n.+?(?=\n)|.+)', s+"\n")

print(result)

结果:

['Line 1\nLine 2', 'Line 3\nline4', 'line5']

"添加换行符作弊"可以正确处理这个问题:
    s = "Line 1\nLine 2\nLine 3\nline4\nline5\nline6"

结果:

['Line 1\nLine 2', 'Line 3\nline4', 'line5\nline6']

1
不错,但对于s =“Line 1 \ nLine 2 \ nLine 3 \ nline4 \ nline5 \ nline6”无效。 - Frane
1
@Frane没错!看看我的修改。简单易懂,处理所有情况,奇数、偶数、以换行符结尾或不是。 - Jean-François Fabre

2
这里提供了一种替代方法,使用grouper itertools配方将任意数量的行分组在一起。
注意:您可以手动实现此配方,也可以选择安装一个第三方库来实现此配方,例如pip install more_itertools
代码:
from more_itertools import grouper


def group_lines(iterable, n=2):
    return ["\n".join((line for line in lines if line))
                    for lines in grouper(n, iterable.split("\n"), fillvalue="")]

演示

s1 = "Line 1\nLine 2\nLine 3"
s2 = "Line 1\nLine 2\nLine 3\nLine4\nLine5"


group_lines(s1)
# ['Line 1\nLine 2', 'Line 3']

group_lines(s2)
# ['Line 1\nLine 2', 'Line 3\nLine4', 'Line5']

group_lines(s2, n=3)
# ['Line 1\nLine 2\nLine 3', 'Line4\nLine5']

细节

group_lines() 函数将字符串按行分割,然后通过 grouper 按照 n 进行分组。

list(grouper(2, s1.split("\n"), fillvalue=""))
[('Line 1', 'Line 2'), ('Line 3', '')]

最后,对于每组行,只有非空字符串才会使用换行符重新连接。

有关grouper的更多详细信息,请参见more_itertools文档


1
我希望我理解您的逻辑是正确的 - 如果您想要一个字符串列表,每个字符串中最多只有一个换行符号,那么以下代码片段将起作用:
# Newline-delimited string
a = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7"
# Resulting list
b = []

# First split the string into "1-line-long" pieces
a = a.split("\n")

for i in range(1, len(a), 2):

    # Then join the pieces by 2's and append to the resulting list
    b.append(a[i - 1] + "\n" + a[i]) 

    # Account for the possibility of an odd-sized list
    if i == len(a) - 2: 
        b.append(a[i + 1])

print(b)

>>> ['Line 1\nLine 2', 'Line 3\nLine 4', 'Line 5\nLine 6', 'Line 7']

尽管这个解决方案不是最快的,也不是最好的,但它易于理解,并且不涉及额外的库。

1

我本想也发布itertools文档中的石斑鱼菜谱,但是PyToolz的partition_all实际上更好一些。

from toolz import partition_all

s = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"
result = ['\n'.join(tup) for tup in partition_all(2, s.splitlines())]
# ['Line 1\nLine 2', 'Line 3\nLine 4', 'Line 5']

为了完整性,这里提供 grouper 的解决方案:

from itertools import zip_longest

# Recipe from the itertools docs.
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

result = ['\n'.join((a, b)) if b else a for a, b in grouper(s, 2)]

-1
使用str.splitlines()将完整输入拆分成行:
>>> inputString = "Line 1\nLine 2\nLine 3"
>>> outputStringList = inputString.splitlines()
>>> print(outputStringList)
['Line 1', 'Line 2', 'Line 3']

然后,将第一行连接起来以获得所需的结果:

>>> result = ['\n'.join(outputStringList[:-1])] + outputStringList[-1:]
>>> print(result)
['Line 1\nLine 2', 'Line 3']

奖励:编写一个函数,可以为任意数量的所需行执行相同的操作:

def split_to_max_lines(inputStr, n):
    lines = inputStr.splitlines()
    # This define which element  in the list become the 2nd in the
    # final result. For n = 2, index = -1, for n = 4, index = -3, etc.
    split_index = -(n - 1)
    result = ['\n'.join(lines[:split_index])]
    result += lines[split_index:]
    return result

print(split_to_max_lines("Line 1\nLine 2\nLine 3\nline 4\nLine 5\nLine 6", 2))
print(split_to_max_lines("Line 1\nLine 2\nLine 3\nline 4\nLine 5\nLine 6", 4))
print(split_to_max_lines("Line 1\nLine 2\nLine 3\nline 4\nLine 5\nLine 6", 5))

返回:

['Line 1\nLine 2\nLine 3\nline 4\nLine 5', 'Line 6']
['Line 1\nLine 2\nLine 3', 'line 4', 'Line 5', 'Line 6']
['Line 1\nLine 2', 'Line 3', 'line 4', 'Line 5', 'Line 6']

-2

我不确定你所说的“最多2行”是什么意思,以及你希望如何实现。然而,按换行符进行分割相当简单。

'Line 1\nLine 2\nLine 3'.split('\n')

这将导致:

['line 1', 'line 2', 'line 3']

要获得“某些”行拆分的奇怪津贴,您将需要编写自己的逻辑。


-2
b = "a\nb\nc\nd".split("\n", 3)
c = ["\n".join(b[:-1]), b[-1]]
print c

提供

['a\nb\nc', 'd']

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