def split_text(text, max_chars_per_segment): """ Splits the input string into multiple substrings, each not exceeding the specified maximum character limit. Preferably splits at newline characters, or at spaces if necessary. Tries to make each substring reach the maximum character limit as much as possible. :param text: The input string to be split. :param max_chars_per_segment: The maximum number of characters allowed in each substring. :return: A list of substrings. """ if len(text) <= max_chars_per_segment: return [text] segments = [] while text: if len(text) <= max_chars_per_segment: segments.append(text) break candidate_text = text[:max_chars_per_segment + 1] # First try to split at newline characters, if no newline character is found, # or the newline character is not close to the maximum length, then try to split at spaces newline_index = candidate_text.rfind('\n') if newline_index != -1 and newline_index >= max_chars_per_segment * 0.6: split_index = newline_index else: space_index = candidate_text.rfind(' ') split_index = space_index if space_index != -1 else max_chars_per_segment segments.append(text[:split_index].strip()) text = text[split_index:].strip() return segments