# Splitting a string without braking a word

**URL:** <https://discuss.python.org/t/splitting-a-string-without-braking-a-word/16600>\
**Category:** Python Help\
**Created:** [June 17, 2022, 5:25pm UTC](https://discuss.python.org/t/splitting-a-string-without-braking-a-word/16600 "2022-06-17T17:25:41Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cheesebird](https://avatars.discourse-cdn.com/v4/letter/c/ecb155/32.png) [@cheesebird](https://discuss.python.org/u/cheesebird)\
**Post date:** [June 17, 2022, 5:25pm UTC](https://discuss.python.org/t/splitting-a-string-without-braking-a-word/16600/1 "2022-06-17T17:25:42Z")

</div>

So I’m looking for a way to split a string without breaking a word and came across this which works but not exactly as I need.

```auto
orig_s = 'I am a noob in python please can you help me break a string without cutting a word'

from textwrap import wrap

print(wrap(orig_s, 26))

```

Output…

```auto
['I a noob in python', 'please can you help me', 'break a string without', 'cutting a word']

```

This is a great module but I need the the first spilt to be 26 and the second to be 40 and even the possibility of a 3rd split if the string is long enough.

Is there anyway to modify textwrap to do this or any alternative suggestions?

---

<div class="post-metadata">

**Author:** ![cheesebird](https://avatars.discourse-cdn.com/v4/letter/c/ecb155/32.png) [@cheesebird](https://discuss.python.org/u/cheesebird)\
**Post date:** [June 17, 2022, 6:14pm UTC](https://discuss.python.org/t/splitting-a-string-without-braking-a-word/16600/2 "2022-06-17T18:14:49Z")

</div>

Regex to the rescue …

```auto
cheese = re.findall('(.{1,26}(?:\s))(.{27,67}(?:\s|$))',orig_s)

print(cheese)

```

But surely there is a better way?

---

<div class="post-metadata">

**Author:** ![rob42](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rob42/32/8218_2.png) [@rob42](https://discuss.python.org/u/rob42)\
**Post date:** [June 17, 2022, 6:53pm UTC](https://discuss.python.org/t/splitting-a-string-without-braking-a-word/16600/3 "2022-06-17T18:53:13Z")

</div>

> [@cheesebird](#):
>
> But surely there is a better way?

I’m not sure about ‘_better_’, but have you looked at the `.isspace()` method? I’m sure that could be used in a loop so that you ‘know’ if your split lands on a space character.

---

<div class="post-metadata">

**Author:** ![vbrozik](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vbrozik/32/7423_2.png) [@vbrozik](https://discuss.python.org/u/vbrozik)\
**Post date:** [June 17, 2022, 7:18pm UTC](https://discuss.python.org/t/splitting-a-string-without-braking-a-word/16600/4 "2022-06-17T19:18:09Z")

</div>

> [@cheesebird](#):
>
> I need the the first spilt to be 26 and the second to be 40 and even the possibility of a 3rd split if the string is long enough.

Is this what you need?

```python
from textwrap import wrap

orig_s = 'I am a noob in python please can you help me break a string without cutting a word'
width_first = 26
width_rest = 40

initial_indent = ' ' * (width_rest - width_first)
print('\n'.join(wrap(orig_s, width_rest, initial_indent=initial_indent)))

```

```plaintext
              I am a noob in python
please can you help me break a string
without cutting a word

```

If you do not want the spaces at the beginning, remove them using the `str.lstrip()` method.

---

<div class="post-metadata">

**Author:** ![vbrozik](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vbrozik/32/7423_2.png) [@vbrozik](https://discuss.python.org/u/vbrozik)\
**Post date:** [June 17, 2022, 7:34pm UTC](https://discuss.python.org/t/splitting-a-string-without-braking-a-word/16600/5 "2022-06-17T19:34:15Z")

</div>

Regex is a good idea as a simple solution for this (for short texts, not megabytes) but for more than two lines you will need to apply it repeatedly in a loop to split the string to a line and the rest which will be split in the next iteration.

Something like:

```python
result = []
text_rest = orig_str
while text_rest:
    result_line, text_rest = your_regex_splitter(text_rest)
    result.append(result_line)

```

or better make it a generator:

```python
from typing import Iterator

def text_wrap(text: str) -> Iterator[str]:
    while text:
        result_line, text = your_regex_splitter(text)
        yield result_line

```

`your_regex_splitter` should have the line length as an argument.

---

<div class="post-metadata">

**Author:** ![mlgtechuser](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/mlgtechuser/32/7310_2.png) [@mlgtechuser](https://discuss.python.org/u/mlgtechuser)\
**Post date:** [June 18, 2022, 6:46am UTC](https://discuss.python.org/t/splitting-a-string-without-braking-a-word/16600/6 "2022-06-18T06:46:25Z")

</div>

This can be optimized further, but works as requested. Would be a simple function `def:` to move the bulky code into the attic. Certain not to be the fastest option, though…

```auto
orig_sentence = 'I am a noob in python. Please can you help me break a string without cutting a word?'
split_sentence = orig_sentence.split()
line = ''
split_len = 26
wrapped_sentence = []
for word in split_sentence:
    if len(line+word)<split_len:
        line += word + ' '
    else:
        wrapped_sentence.append(line)
        line = word + ' '
        split_len = 40
wrapped_sentence.append(line) #needed to paste the contents of the last 'line'

```

Output:

> `['I am a noob in python. ', 'Please can you help me break a string ', 'without cutting a word? ']`

---

<div class="post-metadata">

**Author:** ![cheesebird](https://avatars.discourse-cdn.com/v4/letter/c/ecb155/32.png) [@cheesebird](https://discuss.python.org/u/cheesebird)\
**Post date:** [June 18, 2022, 7:42am UTC](https://discuss.python.org/t/splitting-a-string-without-braking-a-word/16600/7 "2022-06-18T07:42:44Z")

</div>

> [@mlgtechuser](#):
>
> `orig_sentence = 'I am a noob in python. Please can you help me break a string without cutting a word?'`

Nice thanks works perfectly
