Search code examples
pythonword-wrap

In Python, what's a neat way to recursively wrap text to a set number of characters?


I have this string:

text = "abc def ghi jkl mno pqr stu vwx yz\nabc def ghi jkl mno pqr stu vwx yz"

I wanna wrap it to a character width (e.g. 5) such that it becomes this:

abc d
ef gh
i jkl
 mno 
pqr s
tu vw
x yz
abc d
ef gh
i jkl
 mno 
pqr s
tu vw
x yz

Non-recursively, here's what I've got:

text_in  = text.split("\n")
text_out = []

width = 5
for line in text_in:
    if len(line) < width:
        text_out.append(line)
    else:
        text_out.append(line[:width])
        text_out.append(line[width:])

print("\n".join(text_out))

So, it gets things right only to leading order level:

abc d
ef ghi jkl mno pqr stu vwx yz
abc d
ef ghi jkl mno pqr stu vwx yz

How should this wrapping be done recursively or in some other neat way?


Solution

  • Regex solution:

    import re
    
    def wrap_text(text, width):
        if not width:
            return text
        else:
            return re.sub(r'(.{' + str(width) + '})', '\\1\n', text)
    
    text = "abc def ghi jkl mno pqr stu vwx yz\nabc def ghi jkl mno pqr stu vwx yz"
    

    • (.{<width>}) - capture each <width> number of characters into the 1st parenthesized group (...)

    Test case #1:

    print(wrap_text(text, 5))
    

    The output:

    abc d
    ef gh
    i jkl
     mno 
    pqr s
    tu vw
    x yz
    abc d
    ef gh
    i jkl
     mno 
    pqr s
    tu vw
    x yz
    

    Test case #2:

    print(wrap_text(text, 10))
    

    The output:

    abc def gh
    i jkl mno 
    pqr stu vw
    x yz
    abc def gh
    i jkl mno 
    pqr stu vw
    x yz