在python的最大行长内用新行字符替换空格

时间:2019-04-24 16:10:16

标签: python python-3.x

我正在尝试编写python脚本, 将连续的字符串分成几行, 超过max_line_length时。

它不会断言, 并搜索最后出现的空白字符, 它将被换行符替换。

由于某种原因,它没有超出指定的限制。
例如。在定义max_line_length = 80时, 文本有时会在82或83处中断,等等。

由于我花了很长时间试图解决问题, 但是感觉就像我在隧道视野中 并且在这里看不到问题:

#!/usr/bin/python
import sys

if len(sys.argv) < 3:
    print('usage:   $ python3 breaktext.py <max_line_length> <file>')
    print('example: $ python3 breaktext.py 80 infile.txt')
    exit()

filename = str(sys.argv[2])
with open(filename, 'r') as file:
    text_str = file.read().replace('\n', '')

    m = int(sys.argv[1])        # max_line_length
    text_list = list(text_str)  # convert string to list
    l = 0;                      # line_number
    i = m+1                     # line_character_index
    index = m+1                 # total_list_index
    while index < len(text_list):
        while text_list[l * m + i] != ' ':
            i -= 1
            pass
        text_list[l * m + i] = '\n'
        l += 1
        i = m+1
        index += m+1
        pass

    text_str = ''.join(text_list)
    print(text_str)

1 个答案:

答案 0 :(得分:0)

我想我们将从顶部开始。

text_str = file.read().replace('\n', '')

这是一个关于输入数据的假设,我不知道它是否正确。您将所有换行符替换为空;如果它们旁边没有空格,则意味着下面的代码将永远不会在相同位置打断行。

text_list = list(text_str)  # convert string to list

这会将输入文件拆分为单个字符串。我想您可能是这样做的,以使其可变,以便可以替换单个字符,但这是一个非常昂贵的操作,并且会丢失字符串的所有功能。 Python是一种高级语言,可让您分解为例如单词代替。

index = m+1                 # total_list_index
while index < len(text_list):
    #...
    index += m+1

让我们考虑一下这意味着什么。如果index超出了text_list的长度,我们就不会进入循环。但是index正以m+1的步伐前进。因此,我们将math.floor(len(text)/(max_line_length+1))次拆分。除非行都完全是max_line_length个字符,否则不计算换行,而是用换行符替换,否则将是很少的次数。次数太少意味着行太长,至少到最后。

l = 0;                      # line_number
i = m+1                     # line_character_index
#loop:
    while text_list[l * m + i] != ' ':
        i -= 1
    text_list[l * m + i] = '\n'
    l += 1
    i = m+1

这使索引数学变得困难。显然,我们曾经使用的一个索引是l * m + i。这以一种很奇怪的方式移动。它向后搜索一个空格,然后随着l的增加和i的重置而向前跳跃。由于所有的飞跃都以m为步长,因此它反转到的任何位置都将丢失。

让我们将m=5应用于字符串"Fee fie faw fum who did you see now"。对于第一次迭代,0 * 5 + 5+1命中第二个单词,而i则返回第一个空格。如预期的那样,第一行是“费用”。第二个搜索从1*5 + 5+1(这是一个空格)开始,第二行变成“ fie faw”,已经超过了我们的限制5!原因是l * m不是行的开头;它实际上位于“ fie”的中间,这种差异只会在您继续浏览文件时不断扩大。每当您分割短于m的行时,它就会增长。

解决方案包括记住拆分的位置。就像将l * m替换为index并用index += i而不是m+1更新一样简单。

如果遇到超过最大行长的单词,则会产生另一种奇怪的效果。 i除了表示行超出限制之外,还会向后搜索,直到找到空格为止。那么该空间可能会全部位于更早的行中,从而产生额外的短行以及太长的行。这是将整个文本作为一个数组处理,而不是限制我们正在查看的部分的结果。

我个人更喜欢使用Python的内置方法,例如str.rindex,它可以在字符串的给定区域中找到特定字符:

s = "Fee fie faw fum who did you see now"
maxlen = 5
start = 8
end = s.rindex(' ', start, start+maxlen)
print(s[start:end])
start = end + 1

正如PaulMcG所指出的,我们还可以使用完整的“包括电池”,并将标准库textwrap module用于整个任务。