How can I split a text by 1), 2)?

Viewed 202

I want to split my text by subparts 1., 2., ...

import re

s = "1. First sentence. \n2. Second sentence. \n1. Another sentence. \n3. Third sentence."

l = re.compile('\n(?=[0-9].)').split(s)

With my regex I get: ['1. First sentence. ', '2. Second sentence. ', '1. Another sentence. ', '3. Third sentence.']

But I want to split only if the number is superior to the previous one ['1. First sentence. ', '2. Second sentence. 1. Another sentence. ', '3. Third sentence.']

For this example I want a list of 3 elements and not 4.

1 Answers

You can't do that with a regex only, because the regex engine matches text as text and cannot increment or decrement found numeric values and compare them while matching. You can do it only after you get all your matches.

I suggest using a regex that will extract all the bullet points together with their corresponding numbers and then analyze the results and re-build the final list:

import re
s = "1. First sentence. \n2. Second sentence. \n1. Another sentence. \n3. Third sentence."
l = re.findall(r'(?:^|\n)(([0-9]+)\.[\s\S]*?)(?=\n[0-9]+\.|\Z)', s)
curr_num = 0                  # Init the current number to 0
result = []                   # The final bullet point list
for s,num in l:               # Iterate over the list of results
    if curr_num > int(num):   # If curr_num is greater than the number found
        if not result:        # If it is the first item, 
            result = ['']     #    we need to add an empty item
        result[-1] += s       # Append the text to the last item
    else:                     # else
        result.append(s)      # Append the line to the resulting list
    curr_num = int(num)       # Assign the current number
    
print(result) 
# => ['1. First sentence. ', '2. Second sentence. 1. Another sentence. ', '3. Third sentence.']

See the Python demo and the regex demo.

Details:

  • (?:^|\n) - start of string or a newline
  • (([0-9]+)\.[\s\S]*?) - Group 1 matching
    • ([0-9]+) - Group 2: one or more digits
    • \. - a dot
    • [\s\S]*? - any zero or more chars as few as possible
  • (?=\n[0-9]+\.|\Z) - up to the leftmost newline, one or more digits and then a . (\n[0-9]+\.) or end of string (\Z).
Related